Idenya
Dua alat di modul ini membuat query terbaca seperti laporan:
- Alias memberi kolom dan tabel nama yang pendek dan jelas.
CASEadalah if/then/else-nya SQL: ia mengubah nilai mentah menjadi label seperti "budget" atau "premium", dan memungkinkanmu menghitung beberapa kategori dalam satu query.
Alias kolom
Kamu sudah memakai AS untuk menamai kolom hasil perhitungan. Beberapa detail lagi:
SELECT name AS product,
price AS "Unit Price (Rp)",
price - cost AS margin
FROM products
ORDER BY margin DESC
LIMIT 3;
product | Unit Price (Rp) | margin
------------------+-----------------+--------
USB-C Hub | 289000 | 119000
Pour-over Kettle | 320000 | 110000
Desk Lamp LED | 245000 | 105000
(3 rows)
- Alias sederhana (
product,margin) berhuruf kecil dengan garis bawah, seperti variabel Python. - Alias dengan spasi atau huruf kapital butuh kutip ganda:
"Unit Price (Rp)". Itu praktis untuk laporan akhir, tapi canggung untuk dipakai ulang, jadi utamakan nama sederhana di query yang akan dibaca kode lain. ASopsional (price - cost marginjuga bisa), tapi menuliskannya membuat query lebih mudah dibaca.
Di mana kamu bisa memakai alias? Hanya di klausa yang berjalan setelah SELECT:
| Klausa | Berjalan | Bisa memakai alias SELECT? |
|---|---|---|
WHERE | sebelum SELECT | tidak |
HAVING | sebelum SELECT | tidak |
ORDER BY | setelah SELECT | ya |
(PostgreSQL juga mengizinkan GROUP BY memakai alias sebagai kemudahan, tapi banyak database tidak, jadi track ini mengulang ekspresinya di sana.)
Alias tabel
Kamu juga bisa memberi tabel nama pendek dan memakainya untuk mengatakan dari tabel mana sebuah kolom berasal:
SELECT p.name, p.price
FROM products AS p
WHERE p.category = 'Home';
name | price
----------------+--------
Scented Candle | 75000
Throw Pillow | 120000
Bamboo Plant | 60000
(3 rows)
Dengan satu tabel sifatnya opsional. Di modul berikutnya, saat query menggabungkan beberapa tabel yang punya nama kolom sama, alias tabel menjadi penting.
CASE: if/then untuk setiap baris
CASE mengecek kondisi-kondisi secara berurutan dan mengembalikan nilai dari kondisi pertama yang benar:
SELECT name,
price,
CASE
WHEN price < 100000 THEN 'budget'
WHEN price < 200000 THEN 'mid-range'
ELSE 'premium'
END AS price_band
FROM products
ORDER BY price;
name | price | price_band
----------------------+--------+------------
Gel Pen Set | 38000 | budget
Notebook A5 Dotted | 45000 | budget
Ceramic Mug | 55000 | budget
Bamboo Plant | 60000 | budget
Robusta Lampung 250g | 65000 | budget
Scented Candle | 75000 | budget
Desk Organizer | 89000 | budget
Arabica Gayo 250g | 95000 | budget
Toraja Kalosi 250g | 110000 | mid-range
Throw Pillow | 120000 | mid-range
Wireless Mouse | 175000 | mid-range
French Press 600ml | 185000 | mid-range
Desk Lamp LED | 245000 | premium
USB-C Hub | 289000 | premium
Pour-over Kettle | 320000 | premium
(15 rows)
- Setiap
WHEN condition THEN valuediuji dari atas. Yang benar pertama menang, dan sisanya dilewati. ELSEmenangkap sisanya. Tanpanya, baris yang tidak cocok mendapat NULL.- Seluruhnya diakhiri dengan
END, lalu kamu menamainya denganAS.
Karena kecocokan pertama yang menang, urutan itu penting. Lihat apa yang terjadi kalau kondisi yang lebih luas datang lebih dulu:
SELECT name,
price,
CASE
WHEN price >= 100000 THEN 'mid-range'
WHEN price >= 200000 THEN 'premium'
ELSE 'budget'
END AS price_band
FROM products
WHERE price >= 200000;
name | price | price_band
------------------+--------+------------
Pour-over Kettle | 320000 | mid-range
USB-C Hub | 289000 | mid-range
Desk Lamp LED | 245000 | mid-range
(3 rows)
Ketel seharga Rp 320.000 diberi label "mid-range", karena price >= 100000 benar lebih dulu, dan baris premium tidak pernah tercapai. Urutkan kondisi dari yang paling spesifik ke yang paling umum (atau pakai rentang yang tidak bisa tumpang tindih).
Mengelompokkan berdasarkan CASE
CASE membuat kolom baru, dan kamu bisa mengelompokkan berdasarkan kolom itu seperti kolom lainnya:
SELECT CASE
WHEN price < 100000 THEN 'budget'
WHEN price < 200000 THEN 'mid-range'
ELSE 'premium'
END AS price_band,
COUNT(*) AS products
FROM products
GROUP BY 1
ORDER BY products DESC;
price_band | products
------------+----------
budget | 8
mid-range | 4
premium | 3
(3 rows)
GROUP BY 1 berarti "kelompokkan berdasarkan kolom pertama di SELECT". Ini menghemat pengulangan CASE yang panjang, dan umum di pekerjaan analitik.
Agregasi kondisional
Ini salah satu pola paling berguna di SQL analitik. Hitung beberapa hal dalam satu kali jalan dengan menaruh CASE di dalam agregat:
SELECT channel,
COUNT(*) AS orders,
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) AS cancelled
FROM orders
GROUP BY channel
ORDER BY channel;
channel | orders | completed | cancelled
---------+--------+-----------+-----------
app | 12 | 10 | 2
web | 28 | 16 | 8
(2 rows)
Setiap baris menambahkan 1 ke completed kalau ia completed, 0 kalau tidak, jadi SUM-nya menghitung pesanan completed. Kamu sudah mengubah nilai-nilai status menjadi kolom, persis seperti pivot table.
PostgreSQL punya ejaan yang lebih rapi untuk hal yang sama, FILTER:
SELECT channel,
COUNT(*) FILTER (WHERE status = 'completed') AS completed,
ROUND(100.0 * COUNT(*) FILTER (WHERE status = 'cancelled') / COUNT(*), 1) AS cancel_rate
FROM orders
GROUP BY channel
ORDER BY channel;
channel | completed | cancel_rate
---------+-----------+-------------
app | 10 | 16.7
web | 16 | 28.6
(2 rows)
Versi SUM(CASE ...) bekerja di setiap database. FILTER lebih pendek dan lebih enak dibaca, tapi khusus PostgreSQL (dan beberapa database lain).
Mengapa ini penting untuk kode bersih
CASE menaruh aturan bisnis di satu tempat yang terlihat. "Premium berarti Rp 200.000 ke atas" tinggal di query, bukan di ingatan seseorang atau formula Excel yang tersembunyi. Saat aturannya berubah, kamu mengubah satu baris. Pasangkan dengan alias yang jelas dan query-mu menjadi dokumentasi tentang cara sebuah angka dihitung.
Rangkuman
ASmenamai kolom dan tabel; beri tanda kutip pada alias yang punya spasi:"Unit Price".- Alias bisa dipakai di
ORDER BY, tidak diWHEREatauHAVING. - Alias tabel (
products AS p, lalup.name) mempersiapkanmu untuk query multi-tabel. CASE WHEN ... THEN ... ELSE ... ENDmengembalikan nilai dari kondisi pertama yang benar.SUM(CASE WHEN ... THEN 1 ELSE 0 END)atauCOUNT(*) FILTER (WHERE ...)menghitung sebagian data dalam satu kali jalan.