Episode ini membahas cara membaca dan mengolah data: SELECT dengan aliases dan DISTINCT, filtering dengan operator komparasi dan logical, sorting dengan ORDER BY, paging dengan LIMIT OFFSET, serta agregasi data menggunakan GROUP BY dan HAVING.

Di episode ini, kita akan membahas empat kemampuan inti: membaca dan menyaring data dengan SELECT dan WHERE, mengurutkan dengan ORDER BY, melakukan paging dengan LIMIT dan OFFSET, serta mengagregasi data dengan fungsi-fungsi agregat, GROUP BY, dan HAVING.
Perintah paling fundamental: SELECT membaca kolom dari tabel. Gunakan asterisk * untuk semua kolom, atau sebutkan kolom spesifik.
SELECT * FROM users;
SELECT email, full_name FROM users;Alias dengan AS membuat output lebih mudah dibaca, terutama untuk kolom yang dihitung atau kolom dengan nama panjang:
SELECT
email AS alamat_email,
age * 2 AS usia_dobel
FROM users;SELECT DISTINCT category FROM products;
SELECT DISTINCT country FROM customers ORDER BY country;WHERE adalah klausa penyaring. Nilai-nilai ini jadi "senjata utama" filtering kalian:
| Operator | Arti | Contoh |
|---|---|---|
= | Sama dengan | age = 25 |
!= / <> | Tidak sama | status != 'archived' |
<, >, <=, >= | Perbandingan | price > 100000 |
BETWEEN ... AND | Rentang inklusif | age BETWEEN 20 AND 30 |
IN (...) | Anggota daftar | status IN ('new','paid') |
LIKE / ILIKE | Pencocokan pola | name LIKE 'An%' |
IS NULL | Nilai kosong | phone IS NULL |
SELECT email, age
FROM users
WHERE age BETWEEN 20 AND 30
AND is_active = TRUE;Perbedaan kunci untuk pencarian teks di PostgreSQL: LIKE bersifat case-sensitive, sedangkan ILIKE tidak peduli huruf besar/kecil. Karakter wildcard-nya: % cocok dengan nol atau lebih karakter, _ cocok dengan tepat satu karakter.
SELECT email FROM users WHERE email LIKE 'budi%';
SELECT name FROM products WHERE name ILIKE '%sepatu%';Query kedua dengan ILIKE akan menemukan "Sepatu Lari", "sepatu futsal", maupun "SEPATU BOLA" — pencocokan tanpa peduli kapitalisasi.
Gabungkan beberapa kondisi dengan operator logika:
AND: semua kondisi harus benar.OR: minimal satu kondisi benar.NOT: membalikkan hasil kondisi.SELECT email FROM users
WHERE is_active = TRUE
AND (age >= 30 OR country = 'ID')
AND NOT email ILIKE '%@temp.com';Perhatikan tanda kurung di contoh di atas — tanpa kurung, operator OR akan diinterpretasikan dengan prioritas yang mungkin berbeda dari yang kalian maksud. Kurung adalah cara eksplisit menyatakan niat.
ORDER BY mengurutkan hasil query. Defaultnya ASC (kecil ke besar), dan NULL dianggap lebih besar dari semua nilai sehingga muncul terakhir saat ASC. Dengan NULLS FIRST / NULLS LAST, kalian bisa mengontrol posisinya secara eksplisit.
SELECT email, last_login
FROM users
ORDER BY last_login DESC NULLS LAST;LIMIT dan OFFSET:
SELECT email FROM users ORDER BY id LIMIT 20 OFFSET 0;
SELECT email FROM users ORDER BY id LIMIT 20 OFFSET 20;Untuk kepatuhan standar ANSI SQL, PostgreSQL juga mendukung FETCH FIRST n ROWS ONLY:
SELECT name, price FROM products
ORDER BY price DESC
FETCH FIRST 10 ROWS ONLY;Agregasi adalah kemampuan mengubah banyak baris menjadi satu ringkasan. Ini fondasi dari semua laporan dan dashboard.
| Fungsi | Fungsi |
|---|---|
COUNT(*) / COUNT(col) | Menghitung jumlah baris / nilai non-NULL |
SUM(col) | Menjumlahkan nilai numerik |
AVG(col) | Rata-rata nilai |
MIN(col) | Nilai terkecil |
MAX(col) | Nilai terbesar |
SELECT
COUNT(*) AS total_users,
AVG(age) AS rata_usia,
MIN(age) AS termuda,
MAX(age) AS tertua
FROM users;GROUP BY mengelompokkan baris berdasarkan nilai kolom, lalu agregasi dihitung per kelompok:
SELECT country, COUNT(*) AS jumlah_user
FROM users
WHERE is_active = TRUE
GROUP BY country
HAVING COUNT(*) >= 5
ORDER BY jumlah_user DESC;WHERE memfilter baris sebelum dikelompokkan, HAVING memfilter kelompok setelah diagregasi.
SELECT
DATE_TRUNC('month', created_at) AS bulan,
COUNT(*) AS jumlah_order,
SUM(total) AS total_revenue
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY bulan
ORDER BY bulan;DATE_TRUNC('month', ...) memotong timestamp menjadi awal bulan, sehingga semua order di bulan yang sama masuk satu kelompok. Hasilnya adalah laporan penjualan per bulan dalam hitungan detik.
Inti yang harus dibawa pulang:
WHERE memfilter baris; HAVING memfilter kelompok hasil agregasi.ILIKE adalah pencarian teks case-insensitive khas PostgreSQL.ORDER BY punya kontrol NULLS FIRST/LAST yang sering dilupakan.FETCH FIRST n ROWS ONLY adalah alternatif standar ANSI untuk LIMIT.GROUP BY + DATE_TRUNC adalah pasangan andalan untuk laporan waktu.Di episode 6 selanjutnya, kita masuk ke salah satu konsep paling penting dari database relasional: Advanced Table Joins (Relasi Antar Tabel) — mulai dari INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, CROSS JOIN, hingga SELF JOIN untuk data hierarki. Inilah momen di mana database relasional menunjukkan kekuatan sejatinya.