Klausa WHERE dari chapter sebelumnya baru memakai satu jenis kondisi: =. Dalam bahasa sehari-hari kita juga bertanya “yang harganya di bawah lima ribu”, “bukan kategori Kertas”, atau “tanggal sesudah Februari” — semuanya butuh operator perbandingan yang berbeda. MySQL menyediakan enam operator inti yang bekerja pada angka, teks, dan tanggal sekaligus. Pada chapter ini kita akan menguji keenam operator tersebut satu per satu, membuktikan bahwa perbandingan teks bawaan MySQL tidak membedakan huruf besar-kecil, lalu membongkar perilaku paling mengejutkan: membandingkan NULL dengan operator apa pun tidak menghasilkan error, melainkan hasil kosong.
Menyiapkan Tabel Latihan #
Kita pakai kembali pola data toko alat tulis. Chapter ini membutuhkan tiga tabel: produk untuk perbandingan angka dan teks, pesanan untuk perbandingan tanggal, serta pelanggan yang kolom telepon-nya sengaja dibiarkan NULL pada sebagian baris sebagai bahan uji:
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: 0CREATE TABLE pelanggan (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(100) NOT NULL,
kota VARCHAR(50) NOT NULL,
telepon VARCHAR(20) NULL
);
INSERT INTO pelanggan (nama, kota, telepon) VALUES
('Budi Santoso', 'Bandung', '0812-5000-1001'),
('Siti Rahayu', 'Jakarta', '0813-5000-1002'),
('Andi Wijaya', 'Surabaya', NULL),
('Dewi Lestari', 'Bandung', '0815-5000-1004'),
('Rian Hidayat', 'Yogyakarta', NULL),
('Maya Putri', 'Medan', '0817-5000-1006'),
('Eko Prasetyo', 'Semarang', NULL),
('Fitri Handayani', 'Bandung', '0819-5000-1008');Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 8 rows affected (0.00 sec)
Records: 8 Duplicates: 0 Warnings: 0CREATE 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: 0Enam Operator Inti #
Tabel berikut merangkum keenam operator perbandingan beserta artinya. Seluruh operator mengembalikan nilai boolean: 1 bila benar, 0 bila salah, dan NULL bila salah satu sisi belum diketahui nilainya.
| Operator | Arti | Contoh kondisi |
|---|---|---|
= | sama dengan | harga = 5000 |
<> atau != | tidak sama dengan | kategori <> 'Kertas' |
< | kurang dari | stok < 50 |
<= | kurang dari atau sama dengan | harga <= 5000 |
> | lebih dari | harga > 10000 |
>= | lebih dari atau sama dengan | harga >= 10000 |
Kita mulai dari operator = yang sudah kita kenal, lalu pasangannya <>:
SELECT nama, kategori
FROM produk
WHERE kategori = 'Perekat'
ORDER BY id;Output yang Dihasilkan:
+----------------+----------+
| nama | kategori |
+----------------+----------+
| Stipo 12 Gram | Perekat |
| Selotip Bening | Perekat |
+----------------+----------+
2 rows in set (0.00 sec)SELECT nama, kategori
FROM produk
WHERE kategori <> 'Alat Tulis'
ORDER BY id;Output yang Dihasilkan:
+----------------+----------+
| nama | kategori |
+----------------+----------+
| Kertas HVS A4 | Kertas |
| Kertas Origami | Kertas |
| Amplop Coklat | Kertas |
| Stipo 12 Gram | Perekat |
| Selotip Bening | Perekat |
+----------------+----------+
5 rows in set (0.00 sec)Kondisi pertama meloloskan dua produk Perekat, sedangkan kondisi kedua membaliknya menjadi lima produk di luar Alat Tulis. Operator != memiliki arti yang persis sama dengan <>; keduanya sama-sama valid di MySQL 8.4, seperti bukti berikut:
SELECT 5 != 5 AS pakai_seru, 5 <> 5 AS pakai_lebih_kecil;Output yang Dihasilkan:
+------------+-------------------+
| pakai_seru | pakai_lebih_kecil |
+------------+-------------------+
| 0 | 0 |
+------------+-------------------+
1 row in set (0.00 sec)Perbandingan pada Angka #
Empat operator sisanya paling natural dipakai pada kolom angka. Query berikut mengambil produk dengan harga paling banyak 5000:
SELECT nama, harga
FROM produk
WHERE harga <= 5000
ORDER BY harga;Output yang Dihasilkan:
+--------------------+---------+
| nama | harga |
+--------------------+---------+
| Amplop Coklat | 800.00 |
| Penghapus Putih | 2500.00 |
| Pensil 2B | 3000.00 |
| Buku Tulis Sidu 38 | 4500.00 |
| Pulpen Gel Hitam | 5000.00 |
+--------------------+---------+
5 rows in set (0.00 sec)Lima produk lolos, dan perhatikan bahwa Pulpen Gel Hitam dengan harga tepat 5000 ikut di dalam hasil — inilah makna tanda sama dengan pada operator <=. Bandingkan dengan dua operator ketat berikut:
SELECT nama, harga
FROM produk
WHERE harga > 10000
ORDER BY harga;Output yang Dihasilkan:
+----------------+----------+
| nama | harga |
+----------------+----------+
| Kertas Origami | 12000.00 |
| Kertas HVS A4 | 27500.00 |
+----------------+----------+
2 rows in set (0.00 sec)SELECT nama, harga
FROM produk
WHERE harga >= 10000
ORDER BY harga;Output yang Dihasilkan:
+-----------------+----------+
| nama | harga |
+-----------------+----------+
| Spidol Permanen | 10000.00 |
| Kertas Origami | 12000.00 |
| Kertas HVS A4 | 27500.00 |
+-----------------+----------+
3 rows in set (0.00 sec)Query pertama meloloskan dua produk di atas 10000, sedangkan query kedua meloloskan tiga produk karena Spidol Permanen yang harganya tepat 10000 kini ikut. Selisih satu karakter pada operator bisa mengubah isi hasil — saat menulis query laporan, pastikan keputusan “batas termasuk atau tidak” memang disengaja.
Perbandingan pada Teks #
Perbandingan teks menyimpan kejutan pertama: secara bawaan, MySQL tidak membedakan huruf besar dan kecil. Kita buktikan dengan literal sebelum memakainya di WHERE:
SELECT 'Kopi' = 'kopi' AS hasil_sama;Output yang Dihasilkan:
+------------+
| hasil_sama |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)Perbandingan 'Kopi' = 'kopi' mengembalikan 1 (benar). Perilaku ini berasal dari collation bawaan server:
SELECT @@collation_server AS collation_bawaan;Output yang Dihasilkan:
+--------------------+
| collation_bawaan |
+--------------------+
| utf8mb4_0900_ai_ci |
+--------------------+
1 row in set (0.00 sec)Nama collation utf8mb4_0900_ai_ci bisa dibaca sebagai spesifikasi: _ai berarti accent insensitive (huruf beraksen dianggap sama dengan tanpa aksen) dan _ci berarti case insensitive (besar-kecil diabaikan). Akibatnya, kondisi berikut menemukan produk Kertas walaupun penulisannya kita kecilkan semua:
SELECT nama, kategori
FROM produk
WHERE kategori = 'kertas'
ORDER BY id;Output yang Dihasilkan:
+----------------+----------+
| nama | kategori |
+----------------+----------+
| Kertas HVS A4 | Kertas |
| Kertas Origami | Kertas |
| Amplop Coklat | Kertas |
+----------------+----------+
3 rows in set (0.00 sec)Tiga produk kategori Kertas tetap ditemukan. Bila kita benar-benar membutuhkan perbandingan yang membedakan huruf besar-kecil, operator BINARY memaksa perbandingan byte per byte:
SELECT BINARY 'Kopi' = 'kopi' AS hasil_biner;Output yang Dihasilkan:
+-------------+
| hasil_biner |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)Perbandingan pada Tanggal #
Tanggal dibandingkan secara kronologis dengan literal format 'YYYY-MM-DD'. Kondisi tanggal < '2026-02-01' berarti “tercatat sebelum 1 Februari 2026”:
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)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)Dua pesanan Januari lolos pada query pertama, dan satu pesanan tepat di 1 Februari ditemukan query kedua. Operator <, <=, >, >= bekerja sama persis seperti pada angka — hanya saja “lebih besar” berarti “lebih baru” pada konteks tanggal.
Saat NULL Bertemu Operator Perbandingan #
Kini bagian yang sering menjebak pemula. Tiga pelanggan pada tabel kita tidak punya nomor telepon — nilainya NULL, yang berarti “tidak diketahui”, bukan teks kosong. Kita coba bandingkan NULL langsung:
SELECT NULL = NULL AS cek_sama, NULL <> 5 AS cek_beda;Output yang Dihasilkan:
+----------+----------+
| cek_sama | cek_beda |
+----------+----------+
| NULL | NULL |
+----------+----------+
1 row in set (0.00 sec)Hasilnya bukan 1, bukan 0, melainkan NULL untuk keduanya. Logikanya: “tidak diketahui sama dengan tidak diketahui” tidak bisa dipastikan benar maupun salah, jadi jawabannya tetap tidak diketahui. Konsekuensinya di klausa WHERE sangat nyata:
SELECT nama, telepon
FROM pelanggan
WHERE telepon = NULL;Output yang Dihasilkan:
Empty set (0.00 sec)Tidak ada error yang terjadi — query berjalan mulus, tetapi hasilnya kosong. Baris dengan telepon berisi NULL tidak pernah bernilai benar pada telepon = NULL, dan baris dengan nomor telepon juga bernilai salah, sehingga tidak ada satu pun baris yang lolos. MySQL menyediakan operator khusus <=> (NULL-safe equal) yang memperlakukan dua NULL sebagai sama:
SELECT 5 = NULL AS pembanding_biasa, 5 <=> NULL AS pembanding_aman_null;Output yang Dihasilkan:
+------------------+----------------------+
| pembanding_biasa | pembanding_aman_null |
+------------------+----------------------+
| NULL | 0 |
+------------------+----------------------+
1 row in set (0.00 sec)Operator <=> mengembalikan 0 untuk 5 <=> NULL (nilai berbeda dengan yang tidak diketahui) dan mengembalikan 1 bila kedua sisi sama-sama NULL. Untuk memeriksa NULL secara mudah dibaca, MySQL juga menyediakan kondisi IS NULL yang akan kita bahas tuntas di chapter Is NULL.
Membersihkan Database Latihan #
Perbandingan kita sudah lengkap. Tiga tabel latihan dijatuhkan bersama database-nya:
DROP DATABASE belajar_filter;Output yang Dihasilkan:
Query OK, 3 rows affected (0.00 sec)Nilai 3 rows affected sesuai jumlah tabel yang terhapus: produk, pelanggan, dan pesanan.
Referensi #
- Comparison Functions and Operators — MySQL 8.4 Reference Manual
- String Comparison Functions — MySQL 8.4 Reference Manual
- Character Sets and Collations — MySQL 8.4 Reference Manual
Enam operator perbandingan kini menjadi kosakata lengkap kita. Kondisi nyata jarang berdiri sendiri — “kategori Alat Tulis dan harga di bawah lima ribu atau stok habis” menggabungkan beberapa kondisi sekaligus. Chapter berikutnya memperkenalkan operator logika AND, OR, dan NOT yang merangkai kondisi-kondisi tersebut menjadi satu keputusan akhir.