Membaca seluruh isi tabel hanyalah langkah eksplorasi; di aplikasi nyata kita hampir selalu hanya membutuhkan sebagian baris. Tabel produk sebuah toko bisa berisi ribuan baris, sedangkan halaman “daftar produk kertas” cukup menampilkan belasan baris. Klausa WHERE adalah alat MySQL untuk memilih baris mana saja yang lolos ke hasil query. Pada chapter ini kita akan membedah pola dasar WHERE, menerapkannya pada kolom angka, teks, dan tanggal, lalu membandingkan hasil SELECT * dengan hasil yang sudah tersaring agar manfaat penyaringan terlihat nyata.
Menyiapkan Tabel Latihan #
Seluruh chapter pada Section Filtering dan Sorting memakai pola data yang sama: toko alat tulis kecil dengan tabel produk dan pesanan. Setiap chapter membuat tabelnya sendiri di database belajar_filter sehingga latihan selalu mandiri dan bisa diulang dari nol:
DROP DATABASE IF EXISTS belajar_filter;
CREATE DATABASE belajar_filter;
USE belajar_filter;Output yang Dihasilkan:
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Database changedCREATE TABLE produk (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(100) NOT NULL,
kategori VARCHAR(50) NOT NULL,
harga DECIMAL(10,2) NOT NULL,
stok INT NOT NULL DEFAULT 0
);
INSERT INTO produk (nama, kategori, harga, stok) VALUES
('Buku Tulis Sidu 38', 'Alat Tulis', 4500.00, 120),
('Pensil 2B', 'Alat Tulis', 3000.00, 200),
('Penghapus Putih', 'Alat Tulis', 2500.00, 150),
('Pulpen Gel Hitam', 'Alat Tulis', 5000.00, 80),
('Spidol Permanen', 'Alat Tulis', 10000.00, 45),
('Kertas HVS A4', 'Kertas', 27500.00, 20),
('Kertas Origami', 'Kertas', 12000.00, 60),
('Amplop Coklat', 'Kertas', 800.00, 300),
('Stipo 12 Gram', 'Perekat', 6000.00, 0),
('Selotip Bening', 'Perekat', 8000.00, 55);Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0Tabel pesanan mencatat sembilan transaksi penjualan selama Januari hingga Maret 2026. Kolom tanggal bertipe DATE dan seluruh nilainya kita tulis sebagai literal tanggal tetap, bukan hasil fungsi waktu, supaya hasil latihan selalu sama:
CREATE TABLE pesanan (
id INT AUTO_INCREMENT PRIMARY KEY,
nama_pelanggan VARCHAR(100) NOT NULL,
nama_produk VARCHAR(100) NOT NULL,
jumlah INT NOT NULL,
total DECIMAL(10,2) NOT NULL,
tanggal DATE NOT NULL
);
INSERT INTO pesanan (nama_pelanggan, nama_produk, jumlah, total, tanggal) VALUES
('Budi Santoso', 'Pensil 2B', 10, 30000.00, '2026-01-05'),
('Siti Rahayu', 'Kertas HVS A4', 2, 55000.00, '2026-01-18'),
('Dewi Lestari', 'Spidol Permanen', 3, 30000.00, '2026-02-01'),
('Budi Santoso', 'Kertas Origami', 5, 60000.00, '2026-02-14'),
('Maya Putri', 'Buku Tulis Sidu 38', 20, 90000.00, '2026-02-28'),
('Eko Prasetyo', 'Pulpen Gel Hitam', 4, 20000.00, '2026-03-05'),
('Fitri Handayani', 'Selotip Bening', 6, 48000.00, '2026-03-12'),
('Budi Santoso', 'Penghapus Putih', 12, 30000.00, '2026-03-25'),
('Budi Santoso', 'Pulpen Gel Hitam', 2, 10000.00, '2026-03-25');Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0Anatomi Klausa WHERE #
WHERE ditulis setelah FROM dan sebelum ORDER BY atau LIMIT. MySQL memproses query secara bertahap: cari tabel di FROM, uji kondisi WHERE untuk setiap baris, lalu susun kolom hasil sesuai daftar SELECT. Sebuah baris hanya muncul di hasil apabila kondisinya bernilai benar. Sebagai titik banding, kita lihat dulu seluruh isi pesanan tanpa penyaringan:
SELECT * FROM pesanan ORDER BY id;Output yang Dihasilkan:
+----+-----------------+--------------------+--------+----------+------------+
| id | nama_pelanggan | nama_produk | jumlah | total | tanggal |
+----+-----------------+--------------------+--------+----------+------------+
| 1 | Budi Santoso | Pensil 2B | 10 | 30000.00 | 2026-01-05 |
| 2 | Siti Rahayu | Kertas HVS A4 | 2 | 55000.00 | 2026-01-18 |
| 3 | Dewi Lestari | Spidol Permanen | 3 | 30000.00 | 2026-02-01 |
| 4 | Budi Santoso | Kertas Origami | 5 | 60000.00 | 2026-02-14 |
| 5 | Maya Putri | Buku Tulis Sidu 38 | 20 | 90000.00 | 2026-02-28 |
| 6 | Eko Prasetyo | Pulpen Gel Hitam | 4 | 20000.00 | 2026-03-05 |
| 7 | Fitri Handayani | Selotip Bening | 6 | 48000.00 | 2026-03-12 |
| 8 | Budi Santoso | Penghapus Putih | 12 | 30000.00 | 2026-03-25 |
| 9 | Budi Santoso | Pulpen Gel Hitam | 2 | 10000.00 | 2026-03-25 |
+----+-----------------+--------------------+--------+----------+------------+
9 rows in set (0.00 sec)Sembilan baris tampil lengkap dengan seluruh kolomnya. Sekarang kita tambahkan WHERE untuk mengambil hanya pesanan bulan Maret 2026:
SELECT id, nama_pelanggan, tanggal
FROM pesanan
WHERE tanggal >= '2026-03-01'
ORDER BY id;Output yang Dihasilkan:
+----+-----------------+------------+
| id | nama_pelanggan | tanggal |
+----+-----------------+------------+
| 6 | Eko Prasetyo | 2026-03-05 |
| 7 | Fitri Handayani | 2026-03-12 |
| 8 | Budi Santoso | 2026-03-25 |
| 9 | Budi Santoso | 2026-03-25 |
+----+-----------------+------------+
4 rows in set (0.00 sec)Mari kita bedah query di atas baris per baris:
- Baris
SELECT id, nama_pelanggan, tanggal— daftar kolom yang ingin dibaca; tiga dari enam kolom tabel. - Baris
FROM pesanan— sumber baris; MySQL mengambil seluruh baris tabel sebagai kandidat. - Baris
WHERE tanggal >= '2026-03-01'— setiap kandidat diuji: apakahtanggalbaris tersebut tanggal 1 Maret 2026 atau sesudahnya? Baris dengan jawaban salah dibuang. - Baris
ORDER BY id— hasil yang lolos diurutkan menaik berdasarkanidsupaya urutan tampilan selalu sama.
Perbandingan dua hasil di atas memperlihatkan inti WHERE: jumlah baris berkurang dari sembilan menjadi empat, sedangkan data di tabel tidak pernah berubah. Penyaringan terjadi pada hasil query, bukan pada penyimpanan.
Menyaring Baris Berdasarkan Angka #
Kolom bertipe angka disaring dengan operator perbandingan langsung. Query berikut mengambil produk dengan stok kurang dari 50 unit:
SELECT nama, stok
FROM produk
WHERE stok < 50
ORDER BY id;Output yang Dihasilkan:
+-----------------+------+
| nama | stok |
+-----------------+------+
| Spidol Permanen | 45 |
| Kertas HVS A4 | 20 |
| Stipo 12 Gram | 0 |
+-----------------+------+
3 rows in set (0.00 sec)Kondisi stok < 50 menggugurkan tujuh produk dan meloloskan tiga: dua produk yang stoknya menipis serta satu yang stoknya benar-benar habis. Bila kondisi kita persempit menjadi stok = 0, hanya satu baris yang lolos:
SELECT * FROM produk
WHERE stok = 0;Output yang Dihasilkan:
+----+---------------+----------+---------+------+
| id | nama | kategori | harga | stok |
+----+---------------+----------+---------+------+
| 9 | Stipo 12 Gram | Perekat | 6000.00 | 0 |
+----+---------------+----------+---------+------+
1 row in set (0.00 sec)Query di atas meloloskan tepat satu baris — Stipo 12 Gram — sehingga pola WHERE kolom = nilai juga cocok dipakai untuk mencari satu baris spesifik, misalnya berdasarkan id.
Menyaring Baris Berdasarkan Teks #
Nilai teks ditulis sebagai string literal di dalam tanda kutip tunggal. Query berikut mengambil seluruh produk kategori Kertas:
SELECT nama, kategori, harga
FROM produk
WHERE kategori = 'Kertas'
ORDER BY id;Output yang Dihasilkan:
+----------------+----------+----------+
| nama | kategori | harga |
+----------------+----------+----------+
| Kertas HVS A4 | Kertas | 27500.00 |
| Kertas Origami | Kertas | 12000.00 |
| Amplop Coklat | Kertas | 800.00 |
+----------------+----------+----------+
3 rows in set (0.00 sec)Tanda kutip pada 'Kertas' wajib. Tanpa tanda kutip, parser menganggap Kertas sebagai nama kolom, dan karena kolom bernama Kertas tidak ada, query gagal:
-- @error
SELECT nama FROM produk WHERE kategori = Kertas;Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
ERROR 1054 (42S22): Unknown column 'Kertas' in 'where clause'
ByeMenyaring Baris Berdasarkan Tanggal #
Kolom DATE dibandingkan dengan literal tanggal berformat 'YYYY-MM-DD'. Perbandingannya bersifat kronologis: tanggal lebih besar berarti lebih baru. Dua query berikut memakai operator = dan <:
SELECT id, nama_pelanggan, nama_produk
FROM pesanan
WHERE tanggal = '2026-02-01';Output yang Dihasilkan:
+----+----------------+-----------------+
| id | nama_pelanggan | nama_produk |
+----+----------------+-----------------+
| 3 | Dewi Lestari | Spidol Permanen |
+----+----------------+-----------------+
1 row in set (0.00 sec)SELECT id, nama_pelanggan, tanggal
FROM pesanan
WHERE tanggal < '2026-02-01'
ORDER BY id;Output yang Dihasilkan:
+----+----------------+------------+
| id | nama_pelanggan | tanggal |
+----+----------------+------------+
| 1 | Budi Santoso | 2026-01-05 |
| 2 | Siti Rahayu | 2026-01-18 |
+----+----------------+------------+
2 rows in set (0.00 sec)Query pertama menemukan satu pesanan tepat di tanggal 1 Februari 2026, sedangkan query kedua mengambil dua pesanan yang tercatat sebelum tanggal tersebut. Rentang tanggal seperti “sepanjang Februari” akan lebih praktis ditulis dengan BETWEEN — operator yang akan kita bahas tuntas di chapter khusus.
Membersihkan Database Latihan #
Latihan pada chapter ini selesai. Database belajar_filter dan dua tabel di dalamnya boleh dihapus agar server latihan tetap rapi:
DROP DATABASE belajar_filter;Output yang Dihasilkan:
Query OK, 2 rows affected (0.00 sec)Nilai 2 rows affected pada respons di atas menghitung jumlah tabel yang ikut dijatuhkan — produk dan pesanan — sesuai perilaku DROP DATABASE yang melaporkan jumlah tabelnya.
Referensi #
- SELECT Statement — MySQL 8.4 Reference Manual
- Comparison Functions and Operators — MySQL 8.4 Reference Manual
- WHERE Clause Optimization — MySQL 8.4 Reference Manual
Kita kini bisa menyaring baris dengan satu kondisi sederhana. Kondisi nyata di aplikasi lebih kaya dari itu — harga di bawah sekian, pelanggan bukan dari kota tertentu, tanggal di antara dua batas. Chapter berikutnya membedah satu per satu operator perbandingan yang menjadi kosakata lengkap klausa WHERE, termasuk perilaku khasnya pada teks dan NULL.