Belajar SQL PostgreSQL - Subqueries, Set Operations & Expressions
Episode 7 of 21

Belajar SQL PostgreSQL - Subqueries, Set Operations & Expressions

Episode ini membahas subquery di clause WHERE FROM dan SELECT, logika percabangan CASE WHEN, fungsi penanganan NULL COALESCE dan NULLIF, serta operasi himpunan UNION, INTERSECT, dan EXCEPT untuk menggabungkan hasil beberapa query.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Selamat datang di episode 7 series Belajar SQL PostgreSQL! Pada episode 6, kita sudah belajar menggabungkan tabel dengan join. Sekarang kita akan memperluas kosakata SQL dengan tiga kemampuan penting: subquery (query di dalam query), conditional expressions (logika percabangan di SQL), dan set operations (operasi matematika himpunan antar hasil query).

Di episode ini, kita akan membahas subquery di clause WHERE dengan operator IN, EXISTS, ANY, dan ALL, subquery di clause FROM (derived tables) dan SELECT, logika percabangan CASE WHEN, fungsi penanganan NULL COALESCE dan NULLIF, lalu operasi himpunan UNION, INTERSECT, dan EXCEPT.

Subqueries: Query di Dalam Query

Subquery adalah query SELECT yang bersarang di dalam query lain. Ia bisa muncul di berbagai clause, dan hasilnya bisa berupa nilai tunggal, daftar nilai, atau sebuah tabel penuh.

Subquery di Clause WHERE

Posisi paling umum: subquery sebagai filter. Operator yang sering dipakai:

  • IN: memeriksa apakah nilai termasuk dalam hasil subquery.
  • EXISTS / NOT EXISTS: memeriksa apakah subquery menghasilkan setidaknya satu baris.
  • ANY: membandingkan dengan "setidaknya satu" nilai hasil subquery.
  • ALL: membandingkan dengan "semua" nilai hasil subquery.
Subquery dengan IN
SELECT email, full_name
FROM users
WHERE id IN (
    SELECT customer_id
    FROM orders
    WHERE total > 1000000
);

EXISTS adalah alternatif yang sering lebih efisien karena berhenti di baris pertama yang cocok:

Subquery dengan EXISTS
SELECT email, full_name
FROM users u
WHERE EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.customer_id = u.id
      AND o.total > 1000000
);

Perhatikan korelasi: subquery di atas mereferensikan u.id dari query luar. Ini disebut correlated subquery — subquery dievaluasi per baris query luar.

Subquery di Clause FROM (Derived Tables)

Subquery di FROM menghasilkan tabel sementara yang disebut derived table. Ia harus diberi alias, dan kolomnya bisa dipakai seperti tabel biasa:

Subquery di FROM
SELECT email, total_belanja
FROM (
    SELECT
        customer_id,
        SUM(total) AS total_belanja
    FROM orders
    GROUP BY customer_id
) AS ringkasan
JOIN users u ON u.id = ringkasan.customer_id
ORDER BY total_belanja DESC;

Subquery di Clause SELECT

Subquery juga bisa menjadi kolom hasil. Ia harus mengembalikan nilai tunggal (scalar subquery):

Subquery di SELECT
SELECT
    email,
    (SELECT COUNT(*) FROM orders o WHERE o.customer_id = u.id) AS jumlah_order
FROM users u
ORDER BY jumlah_order DESC;

Conditional Expressions

CASE WHEN: Logika Percabangan di SQL

CASE WHEN adalah cara SQL melakukan if-then-else. Ia mengembalikan nilai berbeda berdasarkan kondisi:

CASE WHEN
SELECT
    name,
    price,
    CASE
        WHEN price > 1000000 THEN 'mahal'
        WHEN price > 100000 THEN 'menengah'
        ELSE 'terjangkau'
    END AS kategori_harga
FROM products;

Bentuk CASE value WHEN juga bisa mengecek kesamaan nilai secara ringkas:

CASE dengan pencocokan nilai
SELECT
    order_id,
    status,
    CASE status
        WHEN 'new' THEN 'pesanan baru'
        WHEN 'paid' THEN 'sudah dibayar'
        ELSE 'status lain'
    END AS deskripsi_status
FROM orders;

COALESCE dan NULLIF

Dua fungsi paling berguna untuk menangani NULL:

  • COALESCE(nilai, default): mengembalikan nilai pertama yang bukan NULL dari daftar argumen.
  • NULLIF(a, b): mengembalikan NULL jika a = b, selain itu mengembalikan a. Berguna untuk menghindari pembagian dengan nol.
COALESCE dan NULLIF
SELECT
    email,
    COALESCE(phone, 'belum diisi') AS telepon,
    NULLIF(age, 0) AS usia
FROM users;

Warning

Jangan tertukar: COALESCE memberi nilai pengganti untuk NULL, sedangkan IS NULL hanya memeriksa keberadaan NULL. Dan ingat, NULL di SQL bukan 0 dan bukan string kosong — ia berarti "nilai tidak diketahui", sehingga NULL = NULL hasilnya bukan TRUE melainkan NULL!

Set Operations: Operasi Himpunan

Set operations menggabungkan hasil dari beberapa query — berbeda dengan join yang menggabungkan kolom. Hasilnya adalah baris-baris yang disusun vertikal. Syaratnya: jumlah dan tipe kolom dari setiap query harus kompatibel.

UNION vs UNION ALL

UNION menggabungkan hasil dua query dan menghilangkan duplikat. UNION ALL menggabungkan tanpa menghilangkan duplikat.

UNION vs UNION ALL
SELECT customer_id FROM orders_2025
UNION
SELECT customer_id FROM orders_2026;
 
SELECT customer_id FROM orders_2025
UNION ALL
SELECT customer_id FROM orders_2026;

Query pertama: daftar customer yang pernah order di 2025 atau 2026, unik. Query kedua: semua baris — customer yang order di kedua tahun muncul dua kali. UNION ALL lebih cepat karena tidak perlu proses deduplikasi, jadi pakai ia jika duplikat memang diizinkan.

INTERSECT dan EXCEPT

  • INTERSECT: baris yang muncul di kedua query.
  • EXCEPT: baris yang muncul di query pertama tapi tidak di query kedua.
INTERSECT dan EXCEPT
SELECT customer_id FROM orders_2026
INTERSECT
SELECT customer_id FROM orders_2025;
 
SELECT customer_id FROM customers_2026
EXCEPT
SELECT customer_id FROM customers_2025;

Query pertama: customer yang order di kedua tahun. Query kedua: customer baru (ada di 2026 tapi tidak di 2025).

Penutup

Inti yang harus dibawa pulang:

  • Subquery bisa muncul di WHERE, FROM, dan SELECT — masing-masing punya aturan hasil (nilai, tabel, atau scalar).
  • EXISTS sering lebih efisien untuk correlated subquery.
  • CASE WHEN adalah if-then-else di SQL; COALESCE dan NULLIF adalah senjata melawan NULL.
  • UNION ALL lebih cepat daripada UNION jika deduplikasi tidak diperlukan.
  • INTERSECT dan EXCEPT adalah alat analisis data antar periode yang ampuh.

Di episode 8 selanjutnya, kita akan melihat sisi PostgreSQL yang membuatnya disebut database hybrid: Advanced Data Types: JSONB & Array Support — mulai dari perbedaan JSON dan JSONB, operator query JSON seperti -> dan @>, fungsi manipulasi jsonb_set, hingga tipe data array dengan operator ANY, @>, dan UNNEST. Bersiaplah, karena di sinilah PostgreSQL mulai terasa istimewa.

Belajar SQL PostgreSQL - Subqueries, Set Operations & Expressions | Belajar SQL PostgreSQL