Setelah di Artikel Pertama kita sudah berhasil menyiapkan environment PostgreSQL menggunakan Docker dan memahami perintah dasar pembentukan skema (DDL) serta manipulasi data (DML), sekarang saatnya kita melangkah ke tahap yang paling sering dilakukan dalam kehidupan sehari-hari seorang software engineer: mengambil dan menyaring data.
Banyak pengembang menganggap perintah
SELECT adalah hal yang sepele. "Ah, cuma SELECT * FROM table, apa susahnya?" Namun di dunia kerja nyata, menarik seluruh data menggunakan tanda bintang (*) adalah salah satu penyebab utama aplikasi melambat, memory footprint membengkak, dan database server mengalami kemacetan (bottleneck).Pada artikel kedua ini, kita akan membongkar cara kerja klausa
SELECT dan WHERE, memahami teknik filtering data tingkat lanjut, serta bagaimana SQL Engine memproses query yang kita tulis di balik layar.1. Anatomi Perintah SELECT: Mengapa SELECT * Adalah Antipattern?
Secara sederhana, perintah
SELECT digunakan untuk menentukan kolom mana saja yang ingin kita tampilkan dari satu atau beberapa tabel.Bahasa Deklaratif & Alur Eksekusi Logical
Ketika kamu menulis baris perintah SQL, urutan penulisan kode berbeda dengan urutan bagaimana database mengeksekusinya di balik layar.
SQL
-- Urutan Penulisan (Syntax Order)
SELECT id, username, email
FROM users
WHERE is_active = TRUE;
Di balik layar, SQL Engine memprosesnya dengan alur seperti ini:
-
FROM users: Database menentukan tabel sumber data terlebih dahulu. -
WHERE is_active = TRUE: Database menyaring baris-baris (rows) yang tidak memenuhi kondisi. -
SELECT id, username, email: Database baru memilih dan memproyeksikan kolom-kolom (columns) yang diminta dari hasil penyaringan.
Bahaya Bahaya Latent SELECT *
Menulis
SELECT * FROM posts; memang cepat saat fase prototyping. Namun, membawa kebiasaan ini ke lingkungan produksi (production) sangat tidak disarankan karena beberapa alasan:-
Pemborosan I/O & Memori: Memaksa database membaca kolom yang tidak dibutuhkan (terutama kolom bertipe teks panjang seperti
kontenatauJSONB) dari disk ke RAM, lalu mengalirkannya melalui jaringan ke aplikasi kamu. -
Merusak Cache Aplikasi: Menambah kolom baru di tabel akan mengubah bentuk payload data yang ditarik, yang bisa merusak mekanisme caching atau serialization di sisi kode backend.
-
Penyebab Query Lambat:
SELECT *sering kali mencegah PostgreSQL memanfaatkan Index-Only Scan (fitur di mana database cukup membaca indeks tanpa perlu menyentuh disk utama).
Best Practice: Selalu sebutkan secara eksplisit nama kolom yang kamu butuhkan.
SQL-- GOOD PRACTICE SELECT id, judul, status FROM posts;
2. Menyaring Data Spesifik dengan Klausa WHERE & Operator Logika
Klausa
WHERE digunakan untuk memfilter baris data (rows) berdasarkan kriteria tertentu. Hanya baris yang menghasilkan nilai evaluasi TRUE yang akan dikembalikan oleh database.Mari kita gunakan sampel data dari [Artikel 1] (tabel
users dan posts) untuk mempraktikkan query di bawah ini.A. Operator Perbandingan Standard (=, !=, <, >, <=, >=)
SQL
-- Mengambil pengguna yang berstatus aktif
SELECT id, username, email
FROM users
WHERE is_active = TRUE;
-- Mengambil postingan selain berstatus 'draft'
SELECT id, judul, status
FROM posts
WHERE status != 'draft'; -- atau menggunakan operator <>
B. Menggabungkan Kondisi: AND, OR, dan NOT
Kamu bisa mengombinasikan beberapa syarat penyaringan menggunakan operator logika.
SQL
-- Mengambil postingan milik user_id = 1 DAN berstatus 'published'
SELECT id, judul, status
FROM posts
WHERE user_id = 1 AND status = 'published';
-- Mengambil postingan yang statusnya 'draft' ATAU milik user_id = 2
SELECT id, judul, user_id, status
FROM posts
WHERE status = 'draft' OR user_id = 2;
Hati-hati dengan Prioritas Operator (Precedence):
Operator
AND memiliki prioritas lebih tinggi daripada OR. Jika kamu menggabungkannya dalam satu query, selalu gunakan tanda kurung () untuk memperjelas logika yang diinginkan.SQL
-- Dapatkan post milik user 1 atau user 2, TAPI hanya yang statusnya 'published'
SELECT id, judul, user_id, status
FROM posts
WHERE (user_id = 1 OR user_id = 2)
AND status = 'published';
3. Filtering Tingkat Lanjut: Range, List, dan Pattern Matching
Dalam aplikasi nyata, pencarian data jarang sekali menggunakan persis sama dengan (
=). Kita sering kali harus mencari data berdasarkan rentang angka, pilihan daftar (list), atau pencarian teks (search bar).A. Menggunakan IN dan NOT IN (Filtering Daftar Value)
Daripada menulis rentetan
OR yang panjang (WHERE id = 1 OR id = 2 OR id = 5), gunakan operator IN:SQL
-- Mengambil user berdasarkan ID tertentu
SELECT id, username, nama_lengkap
FROM users
WHERE id IN (1, 2, 5);
-- Mengecualikan status tertentu
SELECT id, judul, status
FROM posts
WHERE status NOT IN ('archived', 'deleted');
B. Menggunakan BETWEEN (Filtering Rentang Nilai/Tanggal)
Operator
BETWEEN bersifat inclusive (artinya batas awal dan batas akhir ikut dihitung).SQL
-- Mengambil artikel yang dibuat sepanjang bulan November 2025
SELECT id, judul, created_at
FROM posts
WHERE created_at BETWEEN '2025-11-01 00:00:00' AND '2025-11-30 23:59:59';
C. Pencarian Teks: LIKE, ILIKE, dan Wildcard
Untuk fitur pencarian (search feature), SQL menyediakan pencarian pola menggunakan simbol wildcard:
-
%(persen): Mewakili nol, satu, atau banyak karakter. -
_(garis bawah): Mewakili tepat satu karakter.
SQL
-- Pencarian Case-Sensitive (LIKE)
-- Mencari judul yang diawali kata 'Panduan'
SELECT id, judul
FROM posts
WHERE judul LIKE 'Panduan%';
-- Mencari judul yang mengandung kata 'Docker' di mana saja
SELECT id, judul
FROM posts
WHERE judul LIKE '%Docker%';
-- Pencarian Case-Insensitive khas PostgreSQL (ILIKE)
-- Akan cocok dengan 'sql', 'SQL', 'Sql', dll.
SELECT id, judul
FROM posts
WHERE judul ILIKE '%sql%';
Catatan Performa: PerintahLIKE '%pola%'(dengan wildcard di depan) tidak bisa menggunakan Indeks B-Tree biasa. Jika tabel kamu memiliki jutaan baris, query ini akan memaksa database melakukan Sequential Scan (membaca seluruh isi tabel dari awal sampai akhir). Untuk pencarian teks berskala besar di PostgreSQL, gunakan Full-Text Search atau indeks GIN/Trigram.
4. Jebakan Paling Sering: Memahami Nilai NULL dan Three-Valued Logic
Banyak bug misterius pada aplikasi backend bersumber dari ketidakfahaman developer terhadap konsep
NULL di dalam SQL.Nilai NULL BUKAN Nol atau String Kosong
NULL di dalam SQL menandakan ketidakadaan nilai (unknown/absence of value). Karena NULL melambangkan sesuatu yang "tidak diketahui", kamu TIDAK BISA membandingkannya menggunakan operator perbandingan biasa seperti = atau !=.SQL
-- SALAH! Query ini TIDAK AKAN mengembalikan data apapun (selalu bernilai FALSE)
SELECT * FROM users WHERE nomor_telepon = NULL;
SELECT * FROM users WHERE nomor_telepon != NULL;
Dalam sistem logika SQL (Three-Valued Logic:
TRUE, FALSE, UNKNOWN), ekspresi NULL = NULL menghasilkan nilai UNKNOWN.Cara Benar Memeriksa NULL
Gunakan operator khusus
IS NULL atau IS NOT NULL:SQL
-- BENAR: Mengambil user yang BELUM mengisi nomor telepon
SELECT id, username, nomor_telepon
FROM users
WHERE nomor_telepon IS NULL;
-- BENAR: Mengambil user yang SUDAH mengisi nomor telepon
SELECT id, username, nomor_telepon
FROM users
WHERE nomor_telepon IS NOT NULL;
Fungsi Penanganan NULL: COALESCE
PostgreSQL menyediakan fungsi bawaan
COALESCE() yang sangat berguna untuk memberikan nilai fallback (default) jika suatu kolom bernilai NULL.SQL
-- Jika nomor_telepon NULL, tampilkan teks 'Belum diisi'
SELECT
username,
COALESCE(nomor_telepon, 'Belum diisi') AS kontak_telepon
FROM users;
5. Ringkasan & Lembar Latihan Mandiri
Memahami cara kerja
SELECT dan WHERE secara presisi adalah fondasi sebelum kita belajar menggabungkan data antar tabel (JOIN) atau melakukan pengelompokan data (GROUP BY).Cheatsheet Operator Filtering:
| Operator | Fungsi | Contoh Kasus |
= / != |
Perbandingan presisi | status = 'published' |
IN (...) |
Memeriksa nilai dalam daftar | id IN (1, 2, 3) |
BETWEEN a AND b |
Memeriksa rentang nilai/tanggal | harga BETWEEN 10000 AND 50000 |
ILIKE '%...%' |
Pencarian teks (case-insensitive) | judul ILIKE '%tutorial%' |
IS NULL |
Memeriksa nilai kosong/absen | deleted_at IS NULL |
🛠️ Latihan Mandiri:
Cobalah tulis query untuk skenario berikut pada database yang sudah kita buat:
-
Tampilkan kolom
id,judul, danstatusdari tabelpostsyang dibuat olehuser_id = 1DAN statusnya BUKAN'draft'. -
Tampilkan semua
usernamedari tabelusersyang mengandung kata'dev'atau'coder'(bebas huruf besar/kecil). -
Tampilkan artikel yang mengandung kata
'Tips'pada judulnya ATAU dibuat setelah tanggal 15 November 2025.
Langkah Selanjutnya
Sekarang kamu sudah bisa mengekstraksi dan memfilter data spesifik sesuai kebutuhan bisnis aplikasi kamu. Namun, data yang ditarik sering kali berantakan urutannya dan terlalu banyak untuk ditampilkan sekaligus dalam satu halaman aplikasi.
Pada Artikel 3: Sorting, Limiting, dan Fungsi Agregat, kita akan mempelajari cara mengurutkan hasil data (
ORDER BY), membatasi jumlah baris untuk fitur pagination (LIMIT & OFFSET), serta menghitung statistik data (COUNT, SUM, AVG, GROUP BY).
Sigit Wasis Subekti
Software Engineer & Tech Educator
Software Engineer and Tech Educator sharing insights on web development and software architecture.