Satu kondisi jarang cukup untuk kebutuhan nyata. Kondisi “produk Alat Tulis” masih terlalu luas, “harga di atas 4000” juga terlalu luas, tetapi “produk Alat Tulis dan harganya di atas 4000” langsung mempersempit ke beberapa baris. Operator logika adalah kata hubung yang merangkai kondisi-kondisi menjadi satu keputusan akhir: AND meminta semua kondisi terpenuhi, OR meminta salah satu saja, dan NOT membalik hasil. Pada chapter ini kita akan mencoba ketiganya di klausa WHERE, memahami tabel kebenarannya, lalu mengintip perilaku khusus ketika NULL ikut serta dalam operasi logika.

Menyiapkan Tabel Latihan #

Kita pakai tabel produk dan pelanggan dengan data yang sama seperti chapter sebelumnya:

sql
DROP DATABASE IF EXISTS belajar_filter;
CREATE DATABASE belajar_filter;
USE belajar_filter;

Output yang Dihasilkan:

text
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
sql
CREATE 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:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0
sql
CREATE 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:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 8 rows affected (0.00 sec)
Records: 8  Duplicates: 0  Warnings: 0

Operator AND — Semua Kondisi Harus Benar #

Operator AND menggabungkan dua kondisi; sebuah baris lolos hanya bila kedua kondisi bernilai benar. Query berikut mencari produk Alat Tulis yang harganya di atas 4000:

sql
SELECT nama, kategori, harga
FROM produk
WHERE kategori = 'Alat Tulis' AND harga > 4000
ORDER BY id;

Output yang Dihasilkan:

text
+--------------------+------------+----------+
| nama               | kategori   | harga    |
+--------------------+------------+----------+
| Buku Tulis Sidu 38 | Alat Tulis |  4500.00 |
| Pulpen Gel Hitam   | Alat Tulis |  5000.00 |
| Spidol Permanen    | Alat Tulis | 10000.00 |
+--------------------+------------+----------+
3 rows in set (0.00 sec)

Mari kita bedah cara MySQL menilai setiap produk Alat Tulis:

  1. Buku Tulis Sidu 38 — kategori sesuai (1) dan harga 4500 > 4000 (1), maka 1 AND 1 menghasilkan 1: lolos.
  2. Pensil 2B — kategori sesuai (1) tetapi harga 3000 > 4000 bernilai 0, maka 1 AND 0 menghasilkan 0: gugur.
  3. Pulpen Gel Hitam dan Spidol Permanen — keduanya memenuhi dua syarat sekaligus, jadi lolos.

Hasil akhirnya tiga baris dari lima produk Alat Tulis. Satu kondisi yang bernilai salah sudah cukup membuat baris gugur — sifat inilah yang membuat AND cocok untuk mempersempit hasil.

Operator OR — Cukup Satu Kondisi Benar #

Operator OR longgar: baris lolos bila minimal satu kondisi bernilai benar. Query berikut mengambil seluruh produk Perekat ditambah produk mana pun yang stoknya habis:

sql
SELECT nama, kategori, stok
FROM produk
WHERE kategori = 'Perekat' OR stok = 0
ORDER BY id;

Output yang Dihasilkan:

text
+----------------+----------+------+
| nama           | kategori | stok |
+----------------+----------+------+
| Stipo 12 Gram  | Perekat  |    0 |
| Selotip Bening | Perekat  |   55 |
+----------------+----------+------+
2 rows in set (0.00 sec)

Hasilnya hanya dua baris: Stipo 12 Gram dan Selotip Bening. Stipo sebenarnya memenuhi kedua kondisi sekaligus — produk Perekat dan stoknya nol — tetapi tetap tampil satu kali. MySQL menguji setiap baris sekali dan memutuskan lolos atau tidak; baris tidak pernah diduplikasi karena memenuhi banyak kondisi.

Operator NOT — Membalik Kondisi #

Operator NOT membalik nilai benar menjadi salah dan sebaliknya. Query berikut mengambil pelanggan yang bukan berasal dari Bandung:

sql
SELECT nama, kota
FROM pelanggan
WHERE NOT kota = 'Bandung'
ORDER BY id;

Output yang Dihasilkan:

text
+--------------+------------+
| nama         | kota       |
+--------------+------------+
| Siti Rahayu  | Jakarta    |
| Andi Wijaya  | Surabaya   |
| Rian Hidayat | Yogyakarta |
| Maya Putri   | Medan      |
| Eko Prasetyo | Semarang   |
+--------------+------------+
5 rows in set (0.00 sec)

Lima dari delapan pelanggan lolos karena tiga pelanggan Bandung tereliminasi. Penulisan NOT kota = 'Bandung' setara dengan kota <> 'Bandung' — keduanya sama-sama sah, dan NOT menjadi berguna ketika kondisi yang dibalik lebih rumit dari satu pembandingan, misalnya membalik hasil OR atau IN yang akan kita temui pada chapter berikutnya.

Tabel Kebenaran Ringkas #

Cara kerja ketiga operator paling mudah dipindai lewat tabel kebenaran. Nilai 1 berarti benar, 0 berarti salah:

Kondisi AKondisi BA AND BA OR BNOT A
11110
10010
01011
00001

Dua hal menonjol dari tabel: AND hanya menghasilkan 1 pada satu baris (semua benar), sedangkan OR hanya menghasilkan 0 pada satu baris (semua salah). Pola ini membuat rangkaian AND panjang makin selektif, sementara rangkaian OR panjang makin longgar.

Ketika NULL Masuk Operasi Logika #

Tabel kebenaran di atas mengasumsikan kedua kondisi pasti 1 atau 0. Kenyataannya, kondisi yang melibatkan NULL menghasilkan NULL — “tidak diketahui” — dan operasi logika ikut menularkannya:

sql
SELECT NULL AND 1 AS dan_null, NULL OR 1 AS atau_null, NOT NULL AS bukan_null;

Output yang Dihasilkan:

text
+----------+-----------+------------+
| dan_null | atau_null | bukan_null |
+----------+-----------+------------+
|     NULL |         1 |       NULL |
+----------+-----------+------------+
1 row in set (0.00 sec)

Tiga hasil menarik: NULL OR 1 menghasilkan 1 (satu sisi saja yang benar sudah cukup untuk OR), sedangkan NULL AND 1 menghasilkan NULL (sisi yang belum diketahui bisa menggagalkan seluruh kondisi), dan NOT NULL tetap NULL. Konsekuensinya, baris dengan kondisi NULL tidak pernah lolos ke hasil query karena MySQL hanya meloloskan kondisi yang benar-benar bernilai 1.

Membersihkan Database Latihan #

Latihan logika selesai. Kita jatuhkan database latihan beserta kedua tabelnya:

sql
DROP DATABASE belajar_filter;

Output yang Dihasilkan:

text
Query OK, 2 rows affected (0.00 sec)

Referensi #

Ketiga operator logika sudah bekerja di tangan kita. Namun ketika AND dan OR bercampur dalam satu WHERE, urutan pengerjaannya menentukan hasil yang sama sekali berbeda — dan di sinilah banyak query diam-diam salah. Chapter berikutnya, AND OR NOT, membuktikannya dengan dua query yang hanya berbeda tanda kurung.