SELECT dan WHERE

Memilih kolom, menyaring baris dengan WHERE, dan mengenal operator perbandingan serta logika.

Daftar isi

Topik ini membahas pernyataan SELECT untuk memilih kolom dan klausa WHERE untuk menyaring baris. Pembahasannya mencakup operator perbandingan, operator logika AND, OR, dan NOT, serta penyingkat syarat berupa BETWEEN, IN, LIKE, dan IS NULL. Basis data latihan dibangun ulang di awal topik, sehingga setiap keluaran pada contoh dapat diulang dari keadaan data yang sama.

Menyiapkan basis data latihan#

Basis data latihan perpustakaan dibangun ulang dari berkas skrip agar seluruh contoh pada topik ini bermula dari data yang sama. Berkas data-perpustakaan.sql memuat pernyataan pembuatan ulang basis data, ketiga tabelnya, dan isinya, yaitu 8 baris anggota, 10 baris buku, dan 12 baris peminjaman. Pernyataan CREATE TABLE beserta tipe datanya memiliki topik tersendiri di jalur ini, sehingga bagian ini hanya memanfaatkan data yang sudah disediakan.

sql data-perpustakaan.sql
-- tidak-dijalankan
-- Berkas latihan jalur MySQL: membangun ulang basis data perpustakaan dari nol.
-- Jalankan dengan: mysql -u root < data-perpustakaan.sql

DROP DATABASE IF EXISTS perpustakaan;
CREATE DATABASE perpustakaan;
USE perpustakaan;

CREATE TABLE anggota (
  id INT PRIMARY KEY,
  nama VARCHAR(60) NOT NULL,
  kota VARCHAR(40) NOT NULL,
  kelas VARCHAR(10) NOT NULL
);

CREATE TABLE buku (
  id INT PRIMARY KEY,
  judul VARCHAR(120) NOT NULL,
  penulis VARCHAR(60) NOT NULL,
  tahun INT NOT NULL,
  stok INT NOT NULL
);

CREATE TABLE peminjaman (
  id INT PRIMARY KEY,
  anggota_id INT NOT NULL,
  buku_id INT NOT NULL,
  tanggal_pinjam DATE NOT NULL,
  tanggal_kembali DATE NULL
);

INSERT INTO anggota (id, nama, kota, kelas) VALUES
  (1, 'Ali Rahman',     'Bandung',  '10A'),
  (2, 'Budi Santoso',   'Bandung',  '10A'),
  (3, 'Citra Lestari',  'Jakarta',  '11B'),
  (4, 'Dewi Anggraini', 'Depok',    '10A'),
  (5, 'Eka Putri',      'Bogor',    '10A'),
  (6, 'Fajar Nugroho',  'Bandung',  '11B'),
  (7, 'Gita Wulandari', 'Jakarta',  '10A'),
  (8, 'Hadi Pratama',   'Semarang', '11B');

INSERT INTO buku (id, judul, penulis, tahun, stok) VALUES
  (1,  'Dasar Basis Data Relasional', 'Ratna Kusuma',   2019, 4),
  (2,  'Algoritma dan Struktur Data', 'Bambang Wijaya', 2021, 2),
  (3,  'Belajar Python dari Nol',     'Ratna Kusuma',   2022, 5),
  (4,  'Jaringan Komputer Dasar',     'Hendra Gunawan', 2018, 1),
  (5,  'Statistika untuk Pemula',     'Sari Wulandari', 2020, 3),
  (6,  'Sejarah Maritim Nusantara',   'Ahmad Fauzi',    2017, 2),
  (7,  'Matematika Diskrit',          'Sari Wulandari', 2021, 2),
  (8,  'Pemrograman Web Sisi Server', 'Bambang Wijaya', 2023, 6),
  (9,  'Fisika Mekanika Dasar',       'Dewi Kartika',   2016, 3),
  (10, 'Sastra Indonesia Modern',     'Ahmad Fauzi',    2019, 4);

INSERT INTO peminjaman (id, anggota_id, buku_id, tanggal_pinjam, tanggal_kembali) VALUES
  (1,  1, 3,  '2025-01-06', '2025-01-13'),
  (2,  3, 2,  '2025-01-08', NULL),
  (3,  2, 1,  '2025-01-10', '2025-01-17'),
  (4,  5, 8,  '2025-01-15', NULL),
  (5,  7, 5,  '2025-01-20', '2025-01-27'),
  (6,  4, 6,  '2025-01-22', '2025-02-03'),
  (7,  6, 3,  '2025-02-05', NULL),
  (8,  8, 10, '2025-02-10', '2025-02-18'),
  (9,  1, 7,  '2025-02-14', NULL),
  (10, 3, 4,  '2025-02-20', '2025-02-25'),
  (11, 2, 9,  '2025-02-24', '2025-03-03'),
  (12, 5, 2,  '2025-03-10', NULL);
bash
# membangun ulang basis data latihan dari berkas skrip
mysql -u root < data-perpustakaan.sql

Perintah di atas tidak mencetak apa pun karena skripnya hanya memuat pernyataan yang mengubah struktur dan mengisi data. Basis data latihan kini berisi 30 baris yang tersebar pada tiga tabel, dan setiap query berikut dibaca terhadap data tersebut.

Memilih kolom dengan SELECT#

Pernyataan SELECT menentukan kolom mana yang dikembalikan, sedangkan klausa FROM menyebut tabel sumbernya. Bentuk paling ringkas memakai tanda bintang untuk meminta seluruh kolom sesuai urutan pendeklarasiannya.

sql Sintaks SELECT
-- tidak-dijalankan
SELECT kolom_1, kolom_2
FROM nama_tabel;
bash
# mengambil seluruh kolom tabel anggota
mysql -t -u root perpustakaan -e "SELECT * FROM anggota;"
text Keluaran
+----+----------------+----------+-------+
| id | nama           | kota     | kelas |
+----+----------------+----------+-------+
|  1 | Ali Rahman     | Bandung  | 10A   |
|  2 | Budi Santoso   | Bandung  | 10A   |
|  3 | Citra Lestari  | Jakarta  | 11B   |
|  4 | Dewi Anggraini | Depok    | 10A   |
|  5 | Eka Putri      | Bogor    | 10A   |
|  6 | Fajar Nugroho  | Bandung  | 11B   |
|  7 | Gita Wulandari | Jakarta  | 10A   |
|  8 | Hadi Pratama   | Semarang | 11B   |
+----+----------------+----------+-------+

Menyebut kolom satu per satu memberi kendali penuh atas isi dan urutan hasil. Urutan kolom pada keluaran mengikuti urutan daftar setelah SELECT, bukan urutan kolom pada tabel.

bash
# mengambil tiga kolom tertentu dari tabel buku
mysql -t -u root perpustakaan -e "SELECT judul, tahun, stok FROM buku;"
text Keluaran
+-----------------------------+-------+------+
| judul                       | tahun | stok |
+-----------------------------+-------+------+
| Dasar Basis Data Relasional |  2019 |    4 |
| Algoritma dan Struktur Data |  2021 |    2 |
| Belajar Python dari Nol     |  2022 |    5 |
| Jaringan Komputer Dasar     |  2018 |    1 |
| Statistika untuk Pemula     |  2020 |    3 |
| Sejarah Maritim Nusantara   |  2017 |    2 |
| Matematika Diskrit          |  2021 |    2 |
| Pemrograman Web Sisi Server |  2023 |    6 |
| Fisika Mekanika Dasar       |  2016 |    3 |
| Sastra Indonesia Modern     |  2019 |    4 |
+-----------------------------+-------+------+

Menyaring baris dengan WHERE#

Klausa WHERE menyaring baris pada saat tabel dibaca, sehingga hanya baris yang memenuhi syarat yang dikembalikan. Server menilai syarat tersebut baris demi baris, dan baris yang dinilai benar diteruskan ke hasil.

sql Sintaks WHERE
-- tidak-dijalankan
SELECT kolom_1, kolom_2
FROM nama_tabel
WHERE syarat;
bash
# menyaring buku yang terbit mulai tahun 2020
mysql -t -u root perpustakaan -e "SELECT judul, tahun FROM buku WHERE tahun >= 2020;"
text Keluaran
+-----------------------------+-------+
| judul                       | tahun |
+-----------------------------+-------+
| Algoritma dan Struktur Data |  2021 |
| Belajar Python dari Nol     |  2022 |
| Statistika untuk Pemula     |  2020 |
| Matematika Diskrit          |  2021 |
| Pemrograman Web Sisi Server |  2023 |
+-----------------------------+-------+

Syaratnya berupa perbandingan antara kolom dan nilai. Nilai string ditulis dalam tanda kutip tunggal, seperti contoh pencarian anggota dari satu kota berikut.

bash
# menyaring anggota dari kota Bandung
mysql -t -u root perpustakaan -e "SELECT nama, kota FROM anggota WHERE kota = 'Bandung';"
text Keluaran
+---------------+---------+
| nama          | kota    |
+---------------+---------+
| Ali Rahman    | Bandung |
| Budi Santoso  | Bandung |
| Fajar Nugroho | Bandung |
+---------------+---------+

Operator perbandingan yang tersedia dirangkum dalam tabel berikut.

OperatorArti
=Sama dengan
<>, !=Tidak sama dengan
<Lebih kecil dari
<=Lebih kecil dari atau sama dengan
>Lebih besar dari
>=Lebih besar dari atau sama dengan

Bentuk <> adalah penulisan baku SQL, sedangkan != merupakan sinonim yang dikenali MySQL dan berperilaku sama. Contoh berikut memakai operator <= untuk menyaring buku yang stoknya tinggal sedikit.

bash
# menyaring buku dengan stok tinggal sedikit
mysql -t -u root perpustakaan -e "SELECT judul, stok FROM buku WHERE stok <= 2;"
text Keluaran
+-----------------------------+------+
| judul                       | stok |
+-----------------------------+------+
| Algoritma dan Struktur Data |    2 |
| Jaringan Komputer Dasar     |    1 |
| Sejarah Maritim Nusantara   |    2 |
| Matematika Diskrit          |    2 |
+-----------------------------+------+

Menggabungkan syarat dengan AND, OR, dan NOT#

Operator logika menggabungkan beberapa syarat menjadi satu syarat gabungan. AND menghasilkan nilai benar hanya apabila kedua syarat yang digabungkan benar. OR menghasilkan nilai benar bila minimal satu syarat benar, sedangkan NOT membalik nilai kebenaran syarat yang mengikutinya.

bash
# buku yang terbit sejak 2020 dan stoknya masih banyak
mysql -t -u root perpustakaan -e "SELECT judul, tahun, stok FROM buku WHERE tahun >= 2020 AND stok >= 3;"
text Keluaran
+-----------------------------+-------+------+
| judul                       | tahun | stok |
+-----------------------------+-------+------+
| Belajar Python dari Nol     |  2022 |    5 |
| Statistika untuk Pemula     |  2020 |    3 |
| Pemrograman Web Sisi Server |  2023 |    6 |
+-----------------------------+-------+------+

Klausa WHERE pada contoh di atas hanya menerima baris yang lolos kedua syarat sekaligus. Satu syarat saja tidak cukup, sehingga Algoritma dan Struktur Data yang terbit pada 2021 tetapi berstok 2 tidak ikut.

bash
# buku yang terbit pada 2019 atau 2021
mysql -t -u root perpustakaan -e "SELECT judul, tahun FROM buku WHERE tahun = 2019 OR tahun = 2021;"
text Keluaran
+-----------------------------+-------+
| judul                       | tahun |
+-----------------------------+-------+
| Dasar Basis Data Relasional |  2019 |
| Algoritma dan Struktur Data |  2021 |
| Matematika Diskrit          |  2021 |
| Sastra Indonesia Modern     |  2019 |
+-----------------------------+-------+

OR lebih longgar, sehingga baris yang memenuhi salah satu syarat saja tetap masuk hasil. NOT membalik syarat, dan penulisan berikut sama artinya dengan kota <> 'Bandung'.

bash
# anggota yang bukan dari Bandung
mysql -t -u root perpustakaan -e "SELECT nama, kota FROM anggota WHERE NOT kota = 'Bandung';"
text Keluaran
+----------------+----------+
| nama           | kota     |
+----------------+----------+
| Citra Lestari  | Jakarta  |
| Dewi Anggraini | Depok    |
| Eka Putri      | Bogor    |
| Gita Wulandari | Jakarta  |
| Hadi Pratama   | Semarang |
+----------------+----------+

Apabila AND dan OR bercampur dalam satu syarat, MySQL menilai AND lebih dahulu. Query berikut dimaksudkan untuk mencari buku dari dua penulis yang terbit sejak 2020, tetapi hasilnya menyertakan buku dari 2017.

bash
# syarat campuran tanpa tanda kurung
mysql -t -u root perpustakaan -e "SELECT judul, penulis, tahun FROM buku WHERE penulis = 'Ahmad Fauzi' OR penulis = 'Ratna Kusuma' AND tahun >= 2020;"
text Keluaran
+---------------------------+--------------+-------+
| judul                     | penulis      | tahun |
+---------------------------+--------------+-------+
| Belajar Python dari Nol   | Ratna Kusuma |  2022 |
| Sejarah Maritim Nusantara | Ahmad Fauzi  |  2017 |
| Sastra Indonesia Modern   | Ahmad Fauzi  |  2019 |
+---------------------------+--------------+-------+

Syarat tahun >= 2020 hanya melekat pada Ratna Kusuma, sedangkan seluruh buku Ahmad Fauzi lolos melalui sisi OR. Agar kedua penulis sama-sama terikat syarat tahun, kelompokkan OR di dalam tanda kurung.

sql Penulisan dengan tanda kurung
-- tidak-dijalankan
SELECT judul, penulis, tahun
FROM buku
WHERE (penulis = 'Ahmad Fauzi' OR penulis = 'Ratna Kusuma') AND tahun >= 2020;

Dengan tanda kurung, server menilai perbandingan penulis lebih dahulu, sehingga hasilnya tinggal satu baris, yaitu Belajar Python dari Nol.

Menyingkat syarat dengan BETWEEN dan IN#

BETWEEN dan IN menyederhanakan pola syarat yang sering muncul. BETWEEN menguji rentang nilai, sedangkan IN menguji keanggotaan dalam sebuah daftar nilai.

bash
# buku yang terbit antara 2018 dan 2020, kedua ujung termasuk
mysql -t -u root perpustakaan -e "SELECT judul, tahun FROM buku WHERE tahun BETWEEN 2018 AND 2020;"
text Keluaran
+-----------------------------+-------+
| judul                       | tahun |
+-----------------------------+-------+
| Dasar Basis Data Relasional |  2019 |
| Jaringan Komputer Dasar     |  2018 |
| Statistika untuk Pemula     |  2020 |
| Sastra Indonesia Modern     |  2019 |
+-----------------------------+-------+

Rentang BETWEEN bersifat inklusif, sehingga baris dengan nilai tepat 2018 dan tepat 2020 ikut masuk. Penulisannya sama artinya dengan tahun >= 2018 AND tahun <= 2020.

bash
# anggota dari dua kota tertentu
mysql -t -u root perpustakaan -e "SELECT nama, kota FROM anggota WHERE kota IN ('Depok', 'Bogor');"
text Keluaran
+----------------+-------+
| nama           | kota  |
+----------------+-------+
| Dewi Anggraini | Depok |
| Eka Putri      | Bogor |
+----------------+-------+

Daftar pada IN ditulis dalam tanda kurung dengan nilai dipisah koma. Penulisannya sama artinya dengan kota = 'Depok' OR kota = 'Bogor', tetapi lebih pendek dan lebih mudah ditambah isinya.

Mencari pola dengan LIKE#

Operator LIKE membandingkan string menurut pola yang memakai dua karakter khusus, yaitu % untuk sejumlah karakter apa pun, termasuk kosong, dan _ untuk tepat satu karakter. Pola diawali maupun diakhiri % sesuai posisi bagian yang dicari.

bash
# buku yang penulisnya bernama depan Bambang
mysql -t -u root perpustakaan -e "SELECT judul, penulis FROM buku WHERE penulis LIKE 'Bambang%';"
text Keluaran
+-----------------------------+----------------+
| judul                       | penulis        |
+-----------------------------+----------------+
| Algoritma dan Struktur Data | Bambang Wijaya |
| Pemrograman Web Sisi Server | Bambang Wijaya |
+-----------------------------+----------------+

Pola Bambang% berarti kata yang diawali Bambang diikuti karakter apa pun, sehingga nama lengkap dengan nama belakangnya tetap lolos. Pola yang meletakkan % di dua ujung mencari potongan kata di posisi mana pun.

bash
# buku yang judulnya memuat kata Komputer
mysql -t -u root perpustakaan -e "SELECT judul, tahun FROM buku WHERE judul LIKE '%Komputer%';"
text Keluaran
+-------------------------+-------+
| judul                   | tahun |
+-------------------------+-------+
| Jaringan Komputer Dasar |  2018 |
+-------------------------+-------+

Menangani nilai kosong dengan IS NULL#

Operator IS NULL menguji kekosongan kolom dan menjadi satu-satunya cara untuk itu, karena NULL tidak pernah sama dengan nilai apa pun, termasuk dengan NULL itu sendiri. Pada tabel peminjaman, kolom tanggal_kembali bernilai NULL selama buku belum dikembalikan.

bash
# peminjaman yang belum dikembalikan
mysql -t -u root perpustakaan -e "SELECT id, anggota_id, buku_id, tanggal_pinjam FROM peminjaman WHERE tanggal_kembali IS NULL;"
text Keluaran
+----+------------+---------+----------------+
| id | anggota_id | buku_id | tanggal_pinjam |
+----+------------+---------+----------------+
|  2 |          3 |       2 | 2025-01-08     |
|  4 |          5 |       8 | 2025-01-15     |
|  7 |          6 |       3 | 2025-02-05     |
|  9 |          1 |       7 | 2025-02-14     |
| 12 |          5 |       2 | 2025-03-10     |
+----+------------+---------+----------------+

Lima baris yang tampil adalah peminjaman yang belum selesai. Query semacam ini biasa dipakai untuk membuat daftar tunggukan pengembalian pada aplikasi perpustakaan.

Kesalahan umum#

Membandingkan dengan = NULL alih-alih IS NULL. Perbandingan biasa terhadap NULL tidak pernah menghasilkan baris, sekalipun kolomnya memang kosong.

bash
# percobaan yang salah: mencari nilai kosong dengan tanda sama dengan
mysql -t -u root perpustakaan -e "SELECT id, tanggal_kembali FROM peminjaman WHERE tanggal_kembali = NULL;"
text Keluaran

Perintahnya berhasil dijalankan, tetapi keluarannya kosong tanpa kepala tabel, karena mode batch tidak mencetak apa pun bila tidak ada baris yang lolos. Perbaikannya adalah mengganti pembanding dengan IS NULL seperti pada contoh bagian sebelumnya.

Menulis string tanpa tanda kutip. Tanpa tanda kutip, kata yang ditulis dianggap pengenal, yaitu nama kolom, bukan nilai string.

bash
# percobaan yang salah: nilai string tanpa tanda kutip
mysql -t -u root perpustakaan -e "SELECT nama FROM anggota WHERE kota = Bandung;"
text Keluaran
ERROR 1054 (42S22) at line 1: Unknown column 'Bandung' in 'where clause'

Server mencari kolom bernama Bandung dan tidak menemukannya, sehingga muncul error Unknown column. Perbaikannya adalah menuliskan nilai string dalam tanda kutip tunggal, yaitu 'Bandung'.

Menyebut tabel tanpa memilih basis data. Query yang dijalankan tanpa basis data default berakhir dengan error, sekalipun nama tabelnya benar.

bash
# percobaan yang salah: tidak ada basis data yang dipilih
mysql -u root -e "SELECT judul FROM buku;"
text Keluaran
ERROR 1046 (3D000) at line 1: No database selected

Perbaikannya adalah menjalankan USE perpustakaan lebih dahulu, atau menuliskan perpustakaan sebagai argumen klien seperti yang dipakai pada seluruh contoh topik ini.

Ringkasan#

  • SELECT menentukan kolom yang dikembalikan dan FROM menyebut tabel sumbernya, sedangkan tanda bintang mengembalikan seluruh kolom.
  • WHERE menyaring baris dengan operator perbandingan, dan syarat majemuk digabungkan dengan AND, OR, serta NOT. Pada syarat campuran, AND dinilai lebih dahulu daripada OR.
  • BETWEEN menyaring rentang inklusif, IN menyaring keanggotaan daftar, LIKE mencari pola dengan % dan _, serta IS NULL menguji kekosongan.
  • NULL tidak pernah sama dengan nilai apa pun, sehingga = NULL tidak pernah mengembalikan baris dan IS NULL menjadi satu-satunya pengujinya.

Referensi#