DataLens

WHERE dan operator perbandingan

Simpan hanya baris-baris yang kamu pedulikan, gabungkan kondisi dengan aman, dan hindari jebakan AND/OR yang diam-diam merusak laporan.

Level: Dasar · 11 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

SELECT memilih kolom. WHERE memilih baris. Bersama-sama keduanya mengubah "tampilkan seluruh tabel" menjadi "tampilkan pesanan app yang completed dari bulan Maret", yang merupakan bentuk pertanyaan sungguhan.

Analogi

WHERE adalah tombol filter di spreadsheet. Setiap baris diuji terhadap kondisimu; baris yang lolos tetap ada, sisanya menghilang dari hasil (tidak dihapus, hanya tidak ditampilkan).

Filter pertamamu

Tabel products berisi 15 produk dari lima kategori. Kalau seorang pelanggan bertanya "kopi apa saja yang kamu jual?", kamu tidak ingin memberinya seluruh daftar lalu membiarkannya mencari sendiri. WHERE menambahkan sebuah kondisi, dan database hanya mengembalikan baris-baris yang memenuhi kondisi itu:

SELECT name, price
FROM products
WHERE category = 'Coffee';
 name                 | price
----------------------+--------
 Arabica Gayo 250g    |  95000
 Robusta Lampung 250g |  65000
 Toraja Kalosi 250g   | 110000
(3 rows)
Awas

Kutip ganda punya arti yang berbeda di SQL. "Coffee" dibaca sebagai nama kolom, jadi WHERE category = "Coffee" gagal dengan column "Coffee" does not exist. Kutip tunggal untuk nilai, selalu.

Perhatikan bahwa category tidak ada di daftar SELECT, tapi kamu tetap bisa memfilter dengannya. Database membaca FROM dulu, lalu WHERE, lalu SELECT, jadi setiap kolom tersedia untuk difilter:

LangkahKlausaApa yang terjadi
1FROM productsbuka tabelnya
2WHERE category = 'Coffee'simpan baris yang cocok
3SELECT name, pricesimpan kolom-kolom ini

Operator perbandingan

OperatorArtinyaContoh
=sama denganstatus = 'completed'
<> atau !=tidak sama denganstatus <> 'cancelled'
< >kurang / lebih dariprice > 200000
<= >=paling banyak / minimalstock <= 20

Semuanya bekerja pada angka, teks (urutan alfabetis), dan tanggal. Tanggal ditulis sebagai teks dalam format 'YYYY-MM-DD':

SELECT order_id, order_date, status
FROM orders
WHERE order_date >= '2024-06-20';
 order_id | order_date | status
----------+------------+-----------
       36 | 2024-06-22 | shipped
       37 | 2024-06-24 | cancelled
       38 | 2024-06-25 | completed
       39 | 2024-06-25 | cancelled
       40 | 2024-06-29 | cancelled
(5 rows)

Menggabungkan kondisi: AND, OR, NOT

SELECT order_id, order_date, channel
FROM orders
WHERE status = 'completed'
  AND channel = 'app'
  AND order_date < '2024-03-01';
 order_id | order_date | channel
----------+------------+---------
        1 | 2024-01-03 | app
        3 | 2024-01-17 | app
        4 | 2024-01-18 | app
        5 | 2024-01-20 | app
        9 | 2024-02-14 | app
(5 rows)

Jebakan AND/OR

Ini pertanyaan dari seorang manajer: "Tampilkan produk kopi atau dapur di bawah Rp 100.000." Percobaan pertama yang wajar:

SELECT name, category, price
FROM products
WHERE category = 'Coffee' OR category = 'Kitchen' AND price < 100000;
 name                 | category | price
----------------------+----------+--------
 Arabica Gayo 250g    | Coffee   |  95000
 Robusta Lampung 250g | Coffee   |  65000
 Toraja Kalosi 250g   | Coffee   | 110000
 Ceramic Mug          | Kitchen  |  55000
(4 rows)

Kopi Toraja harganya Rp 110.000, jadi kenapa ia ada di sana? Karena AND dievaluasi sebelum OR, sama seperti perkalian sebelum penjumlahan di matematika. Database membaca kondisinya sebagai:

category = 'Coffee'  OR  (category = 'Kitchen' AND price < 100000)

Jadi setiap produk kopi lolos, berapa pun harganya. Tanda kurung memperbaikinya:

SELECT name, category, price
FROM products
WHERE (category = 'Coffee' OR category = 'Kitchen')
  AND price < 100000;
 name                 | category | price
----------------------+----------+-------
 Arabica Gayo 250g    | Coffee   | 95000
 Robusta Lampung 250g | Coffee   | 65000
 Ceramic Mug          | Kitchen  | 55000
(3 rows)
Ide utama

Setiap kali sebuah WHERE mencampur AND dan OR, tambahkan tanda kurung, bahkan saat kamu merasa tidak membutuhkannya. Query-nya tetap jalan tanpa error; hanya angkanya yang salah, dan tidak ada yang menyadarinya sampai terlambat.

IN: OR yang lebih pendek

Saat kamu membandingkan satu kolom dengan beberapa nilai, IN lebih rapi daripada rangkaian OR:

SELECT name, category, price
FROM products
WHERE category IN ('Coffee', 'Kitchen')
  AND price < 100000;
 name                 | category | price
----------------------+----------+-------
 Arabica Gayo 250g    | Coffee   | 95000
 Robusta Lampung 250g | Coffee   | 65000
 Ceramic Mug          | Kitchen  | 55000
(3 rows)

NOT IN menyimpan semuanya kecuali nilai-nilai yang didaftar: WHERE status NOT IN ('cancelled', 'pending').

BETWEEN: sebuah rentang

Pelanggan sering berbelanja sesuai anggaran: "sesuatu antara 60 dan 95 ribu". Kamu bisa menulisnya sebagai price >= 60000 AND price <= 95000, tapi BETWEEN mengatakannya dengan lebih alami. BETWEEN low AND high mencakup kedua ujungnya:

SELECT name, price
FROM products
WHERE price BETWEEN 60000 AND 95000;
 name                 | price
----------------------+-------
 Arabica Gayo 250g    | 95000
 Robusta Lampung 250g | 65000
 Desk Organizer       | 89000
 Scented Candle       | 75000
 Bamboo Plant         | 60000
(5 rows)

Tanaman seharga Rp 60.000 dan kopi seharga Rp 95.000 sama-sama termasuk. Untuk tanggal, order_date BETWEEN '2024-03-01' AND '2024-03-31' berarti "seluruh bulan Maret".

Sedikit tentang nilai yang hilang

Dimas tidak punya email, yang disimpan sebagai NULL. Kamu mungkin mencoba WHERE email = NULL, tapi itu tidak mengembalikan baris sama sekali, karena NULL berarti "tidak diketahui" dan "apakah tidak diketahui sama dengan tidak diketahui?" tidak bernilai benar. Pengujian yang benar adalah IS NULL:

SELECT name, email
FROM customers
WHERE email IS NULL;
 name          | email
---------------+-------
 Dimas Pratama | NULL
 Joko Susilo   | NULL
(2 rows)

Modul NULL nanti di track ini membahas detailnya. Untuk sekarang: jangan pernah memakai = NULL, pakai IS NULL atau IS NOT NULL.

Mengapa ini penting untuk kode bersih

Sebagian besar angka yang salah di laporan bukan disebabkan oleh crash, melainkan oleh filter yang jalan dengan baik tapi artinya berbeda dari yang dimaksud penulisnya. Tanda kurung di sekitar OR, IN alih-alih rangkaian OR yang panjang, dan satu kondisi per baris membuat maksudmu mustahil salah dibaca, oleh database maupun oleh orang berikutnya.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: ORDER BY dan LIMIT →