WHERE Memfilter Baris Satu per Satu
SELECT tanpa WHERE mengembalikan setiap baris di tabel. Itu jarang yang kamu inginkan. WHERE memungkinkanmu hanya menyimpan baris yang cocok dengan sebuah kondisi: SQLite menelusuri tabel, mengevaluasi kondisi terhadap setiap baris, dan menyimpan baris yang kondisinya bernilai true.
Tiga baris dikembalikan: Neuromancer, Hyperion, dan The Martian. Kondisi year > 1980 diuji terhadap setiap baris, dan hanya yang cocok yang bertahan.
Model mentalnya: WHERE adalah filter yang berada di antara FROM dan kolom yang kamu pilih. Apa pun yang bernilai true akan lolos.
Operator Perbandingan
Dasar-dasarnya bekerja seperti yang kamu duga:
= untuk kesamaan, != atau <> untuk "tidak sama dengan", serta <, <=, >, >= untuk urutan. Perbandingan string memakai operator yang sama: author = 'Asimov' cocok persis, karakter demi karakter.
Satu hal yang perlu diketahui: SQL memakai tanda kutip tunggal untuk literal string. Tanda kutip ganda dipakai untuk identifier (nama kolom atau tabel). WHERE author = "Asimov" mungkin berjalan di SQLite karena alasan historis, tapi tidak portabel dan bisa diam-diam berperilaku salah saat "string" itu kebetulan sama dengan nama kolom. Tetap pakai tanda kutip tunggal.
AND, OR, dan Tanda Kurung
Query sungguhan biasanya menggabungkan beberapa kondisi. AND mengharuskan kedua sisi bernilai true; OR mengharuskan setidaknya satu:
Query pertama memfilter buku yang baru dan tipis. Query kedua mengambil buku dari salah satu dari dua penulis.
Saat kamu mencampur AND dan OR, urutan prioritas sering menjebak. AND mengikat lebih kuat daripada OR, jadi:
dibaca sebagai Herbert OR (Gibson AND year > 1980): setiap buku Herbert tanpa peduli tahunnya, ditambah buku Gibson setelah 1980. Mungkin bukan itu maksudmu. Bungkus maksudmu dengan tanda kurung:
Kalau ragu, pakai tanda kurung. Query optimizer tidak peduli, dan orang berikutnya yang membaca query itu akan berterima kasih.
NULL Tidak Berperilaku Seperti Nilai
Inilah jebakan klausa WHERE yang pernah menjerat semua orang. NULL di SQL berarti "tidak diketahui", dan hal yang tidak diketahui tidak bisa dibandingkan. column = NULL bukan false: hasilnya NULL, yang diperlakukan WHERE sebagai "lewati baris ini."
IS NULL dan IS NOT NULL adalah satu-satunya operator yang menguji NULL secara langsung. Biasakan jarimu mengetiknya: setiap perbandingan lain dengan NULL mengembalikan NULL dan diam-diam membuang baris.
Aturan yang sama berlaku untuk negasi. WHERE author != 'Asimov' tidak mengembalikan baris dengan author IS NULL, karena NULL != 'Asimov' juga bernilai NULL. Kalau kamu ingin NULL ikut disertakan, mintalah secara eksplisit: WHERE author != 'Asimov' OR author IS NULL.
IN dan BETWEEN: Jalan Pintas yang Akan Kamu Pakai Setiap Hari
IN memeriksa keanggotaan dalam sebuah daftar. Ini cara yang lebih rapi untuk menulis rangkaian OR:
BETWEEN memeriksa sebuah rentang, termasuk kedua ujungnya:
year BETWEEN 1980 AND 2000 identik dengan year >= 1980 AND year <= 2000, hanya lebih singkat. Satu hal yang perlu diingat: kedua batas ikut disertakan. Jika kamu ingin batas yang tidak disertakan, tulis perbandingannya secara lengkap.
Catatan singkat tentang IN dan NULL: WHERE column NOT IN (1, 2, NULL) tidak akan pernah mengembalikan baris, karena membandingkan apa pun dengan NULL menghasilkan NULL. Buang NULL dari daftarmu, atau tangani secara terpisah dengan IS NULL.
LIKE untuk Pencocokan Pola
LIKE melakukan pencocokan pola string dengan dua wildcard:
%cocok dengan deretan karakter apa pun (termasuk tidak ada karakter)._cocok dengan tepat satu karakter.
Secara default, LIKE di SQLite tidak membedakan huruf besar dan kecil untuk huruf ASCII: 'Dune' LIKE 'dune' bernilai true. Ini mengejutkan jika kamu datang dari Postgres, tempat LIKE membedakan huruf besar kecil dan ILIKE adalah versi yang tidak membedakannya. (SQLite tidak punya ILIKE.)
Jika kamu butuh pencocokan yang membedakan huruf besar kecil, ada dua pilihan. Aktifkan pragma global:
PRAGMA case_sensitive_like = ON;
Atau pakai GLOB, yang selalu membedakan huruf besar kecil dan memakai wildcard gaya Unix (* untuk deretan apa pun, ? untuk satu karakter):
GLOB 'd*' tidak akan cocok dengan apa pun di sini, karena huruf besar kecil berpengaruh.
Memfilter Tanggal
SQLite menyimpan tanggal sebagai teks (biasanya YYYY-MM-DD atau ISO 8601 lengkap), artinya perbandingan string kebetulan juga berfungsi sebagai perbandingan tanggal, selama kamu tetap memakai format ISO:
Karena '2024-06-01' < '2024-11-08' bernilai true baik sebagai string maupun sebagai tanggal, query ini bekerja sesuai dugaan. Jika kamu menyimpan tanggal dalam format lain ('15/01/2024', 'Jan 15 2024'), perbandingannya akan diam-diam memberi hasil yang salah. Selalu pakai ISO 8601, dirimu di masa depan akan senang.
Untuk perhitungan tanggal yang lebih rumit (mengambil tahun, membandingkan dengan "hari ini"), SQLite punya fungsi date(), strftime(), dan julianday(). Kita akan membahasnya di bab tanggal dan waktu.
Menggabungkan Semuanya
Query yang memakai beberapa di antaranya sekaligus:
Baca baris demi baris: simpan baris yang tahunnya diketahui, berada dalam rentang, ditulis salah satu dari dua penulis atau cukup tebal, dan bukan draf. Itulah klausa WHERE melakukan keahliannya: menggabungkan kondisi kecil yang mudah dibaca menjadi filter yang presisi.
Dua kebiasaan yang layak dipertahankan:
- Tulis setiap kondisi di barisnya sendiri dengan indentasi. Klausa
WHEREyang panjang cepat jadi sulit dibaca jika ditulis dalam satu baris raksasa. - Beri komentar tentang maksudnya saat kondisinya tidak jelas.
-- exclude draftsadalah asuransi yang murah.
Berikutnya: Operator dan NULL Lebih Rinci
Klausa WHERE sebagian besar berisi operator yang diterapkan pada kolom, dan NULL diam-diam mengubah perilaku setiap operator. Halaman berikutnya membahas lebih dalam kumpulan operator SQLite, yaitu aritmetika, penggabungan string dengan ||, keluarga IS, dan logika tiga nilai, supaya kejutan-kejutan itu tidak lagi mengejutkan.
Pertanyaan yang sering diajukan
Bagaimana cara kerja klausa WHERE di SQLite?
WHERE memfilter baris dari sebuah query dengan menguji kondisi terhadap setiap baris. Baris yang kondisinya bernilai true disimpan; baris yang bernilai false atau NULL dibuang. Klausa ini ditulis tepat setelah FROM: SELECT ... FROM table WHERE condition.
Bagaimana cara menggabungkan beberapa kondisi di klausa WHERE SQLite?
Pakai AND dan OR. AND mengharuskan kedua sisi bernilai true; OR cukup satu. AND mengikat lebih kuat daripada OR, jadi bungkus kondisi campuran dengan tanda kurung agar jelas: WHERE (a OR b) AND c.
Kenapa WHERE column = NULL tidak berfungsi di SQLite?
NULL berarti "tidak diketahui", jadi setiap perbandingan dengan = atau != mengembalikan NULL, bukan true atau false, dan baris hanya disimpan saat kondisinya true. Pakai IS NULL dan IS NOT NULL sebagai gantinya. Hanya kedua operator itu yang menguji NULL secara langsung.
Apakah LIKE di klausa WHERE SQLite membedakan huruf besar dan kecil?
Secara default, LIKE tidak membedakan huruf besar dan kecil untuk karakter ASCII: 'Hello' LIKE 'hello' bernilai true. Untuk pembedaan huruf besar kecil penuh, atur PRAGMA case_sensitive_like = ON; atau pakai GLOB, yang selalu membedakan huruf besar kecil dan memakai wildcard gaya Unix (* dan ?).