Chapter INSERT
sudah mengisi tabel produk dengan enam baris data; sekarang saatnya mengambil data itu kembali. Perintah SELECT adalah operasi database yang paling sering kita jalankan — laporan, tampilan aplikasi, analisis, semuanya bermuara ke satu perintah ini. Pada chapter ini kita fokus pada fondasinya: memilih kolom mana yang ingin dilihat, memberi nama alias pada hasil, menghitung nilai baru langsung di dalam SELECT, lalu menyusun hasil agar tampil dalam urutan yang pasti.
Menyiapkan Tabel Latihan #
Supaya setiap contoh bisa dijalankan sendiri, kita buat ulang tabel produk — kali ini dengan satu kolom tambahan deskripsi yang boleh NULL, karena kolom itu akan memperlihatkan perilaku tampilan nilai NULL:
CREATE TABLE produk (
id integer PRIMARY KEY,
nama text NOT NULL,
kategori text NOT NULL,
harga numeric(10, 2) NOT NULL,
deskripsi text
);
INSERT INTO produk (id, nama, kategori, harga, deskripsi) VALUES
(1, 'Buku Tulis', 'alat tulis', 4500, 'Buku 58 halaman bergaris'),
(2, 'Pulpen Hitam', 'alat tulis', 3000, NULL),
(3, 'Kertas HVS A4', 'kertas', 55000, 'Kertas 70 gram'),
(4, 'Stapler Besar', 'alat tulis', 24000, NULL),
(5, 'Amplop Coklat', 'kertas', 1500, NULL),
(6, 'Penghapus', 'alat tulis', 2000, 'Penghapus putih');Output yang Dihasilkan:
CREATE TABLE
INSERT 0 6Struktur tabel ini sama dengan tabel di chapter INSERT, hanya kolom deskripsi yang baru — dan tiga baris sengaja dibiarkan tanpa deskripsi (NULL). Nilai NULL bukan string kosong; NULL berarti “tidak ada nilainya sama sekali”, dan perbedaan itu akan terlihat di output sebentar lagi.
Memilih Kolom yang Ditampilkan #
Bentuk paling sederhana SELECT menentukan dua hal: kolom apa yang ingin dilihat, dan dari tabel mana datanya diambil. Tanda bintang (*) berarti “semua kolom”:
SELECT * FROM produk ORDER BY id;
SELECT nama, harga FROM produk ORDER BY id;Output yang Dihasilkan:
id | nama | kategori | harga | deskripsi
----+---------------+------------+----------+--------------------------
1 | Buku Tulis | alat tulis | 4500.00 | Buku 58 halaman bergaris
2 | Pulpen Hitam | alat tulis | 3000.00 |
3 | Kertas HVS A4 | kertas | 55000.00 | Kertas 70 gram
4 | Stapler Besar | alat tulis | 24000.00 |
5 | Amplop Coklat | kertas | 1500.00 |
6 | Penghapus | alat tulis | 2000.00 | Penghapus putih
(6 rows)
nama | harga
---------------+----------
Buku Tulis | 4500.00
Pulpen Hitam | 3000.00
Kertas HVS A4 | 55000.00
Stapler Besar | 24000.00
Amplop Coklat | 1500.00
Penghapus | 2000.00
(6 rows)Dua hal penting dari hasil tersebut:
SELECT *mengembalikan semua kolom dalam urutan definisi tabel — lima kolom termasukiddandeskripsi. Praktik ini enak untuk eksplorasi, tetapi di kode aplikasi sebaiknya sebutkan kolom secara eksplisit: kebutuhan transfer data lebih kecil, dan perintah tidak diam-diam berubah perilaku saat struktur tabel berubah.SELECT nama, hargahanya membawa dua kolom itu — kolom lain tetap tersimpan di tabel, hanya tidak ikut ditampilkan.
Perhatikan kolom deskripsi pada hasil pertama: baris Pulpen Hitam, Stapler Besar, dan Amplop Coklat menampilkan sel kosong. Itulah cara psql menampilkan NULL — bukan string kosong ' ', melainkan benar-benar tidak ada nilai. Tanda kosong dan string kosong terlihat sama di layar, sehingga pembeda keduanya perlu operator IS NULL, yang dibahas tuntas di chapter IS NULL pada Section Filtering dan Sorting.
Klausa ORDER BY id pada kedua perintah sengaja dipasang sejak awal: tanpa ORDER BY, PostgreSQL tidak menjamin urutan baris hasil sama sekali. Baris biasanya keluar sesuai urutan penyimpanan, tetapi itu kebetulan implementasi, bukan janji standar SQL.
Alias: Mengganti Nama Kolom Hasil #
Nama kolom seperti harga memang sudah jelas, tetapi hasil perhitungan atau hasil dari tabel yang di-JOIN sering butuh nama yang lebih manusiawi. Alias mengganti judul kolom di hasil — perubahan murni tampilan, tabel aslinya tidak tersentuh:
SELECT nama AS nama_produk, harga harga_rupiah
FROM produk
ORDER BY id;
SELECT nama,
harga * 1.1 AS "Harga Setelah Naik"
FROM produk
ORDER BY id;Output yang Dihasilkan:
nama_produk | harga_rupiah
---------------+--------------
Buku Tulis | 4500.00
Pulpen Hitam | 3000.00
Kertas HVS A4 | 55000.00
Stapler Besar | 24000.00
Amplop Coklat | 1500.00
Penghapus | 2000.00
(6 rows)
nama | Harga Setelah Naik
---------------+--------------------
Buku Tulis | 4950.000
Pulpen Hitam | 3300.000
Kertas HVS A4 | 60500.000
Stapler Besar | 26400.000
Amplop Coklat | 1650.000
Penghapus | 2200.000
(6 rows)Mari kita bedah tiga variasi alias pada contoh di atas:
nama AS nama_produk— bentuk paling eksplisit dengan kata kunciAS. Judul kolom hasil berubah menjadinama_produk.harga harga_rupiah— kataASboleh dihilangkan; cukup kolom diikuti nama alias. Kedua bentuk identik hasilnya, dan memilih salah satunya selera gaya tim.harga * 1.1 AS "Harga Setelah Naik"— alias dua kata atau alias dengan karakter khusus (spasi, kurung, huruf besar campuran) wajib dibungkus kutip dua. Tanpa kutip, PostgreSQL memperlakukanHargadanSetelahsebagai dua identifier terpisah dan menolak perintahnya.
Alias pada kolom hasil juga berguna bagi aplikasi: driver database di PHP, Go, atau Python memakai nama kolom hasil sebagai kunci array/map, dan nama yang deskriptif membuat kode pembaca hasil jauh lebih bersih.
Ekspresi di Dalam SELECT #
Daftar kolom tidak terbatas pada kolom tabel — setiap ekspresi yang sah boleh ditempatkan di sana: aritmetika, penggabungan string dengan operator ||, pemanggilan function, sampai CASE. Perhitungan terjadi per baris, sehingga hasilnya tetap sebaris dengan data aslinya. Contoh kedua di file sebelumnya sudah memperlihatkan harga * 1.1; berikut variasi yang menggabungkan dua operasi sekaligus:
SELECT nama, harga
FROM produk
ORDER BY harga DESC, nama
LIMIT 3;Output yang Dihasilkan:
nama | harga
---------------+----------
Kertas HVS A4 | 55000.00
Stapler Besar | 24000.00
Buku Tulis | 4500.00
(3 rows)Perintah ini menggabungkan tiga teknik sekaligus:
ORDER BY harga DESC, namamengurutkan berdasarkan harga dari yang termahal (DESC= descending), dengannamasebagai pemecah seri bila dua harga sama — kombinasi ini menjamin urutan hasil selalu identik di mesin mana pun.LIMIT 3memotong hasil menjadi tiga baris pertama. PolaORDER BY ... LIMIT nadalah resep dasar query “top-N”: produk termahal, pelanggan terbaru, lima penjualan terbesar. Pembahasan lengkapnya ada di chapter LIMIT dan OFFSET.DESChanya berlaku pada kolom yang dilekatinya —namatetap naik (A ke Z) karena tidak diberiDESC.
Membedakan Nilai Unik dengan DISTINCT #
Kolom kategori hanya berisi dua nilai berbeda, tetapi enam baris menampilkannya berulang. DISTINCT menghilangkan baris hasil yang sama persis:
SELECT kategori FROM produk ORDER BY kategori, id;
SELECT DISTINCT kategori FROM produk ORDER BY kategori;Output yang Dihasilkan:
kategori
------------
alat tulis
alat tulis
alat tulis
alat tulis
kertas
kertas
(6 rows)
kategori
------------
alat tulis
kertas
(2 rows)Perintah pertama mengembalikan enam baris (satu per produk), perintah kedua hanya dua baris: alat tulis dan kertas. DISTINCT bekerja pada seluruh baris hasil — bila dua kolom dipilih, baris duplikat dianggap sama hanya ketika kedua kolomnya identik. Kombinasi DISTINCT dengan ORDER BY juga penting: hasil DISTINCT tanpa ORDER BY tidak menjamin urutan, dan kita membutuhkan urutan yang pasti agar output latihan ini reproducible. Pemanfaatan DISTINCT yang lebih dalam — DISTINCT ON, interaksi dengan agregasi — dibahas di chapter DISTINCT pada Section Filtering dan Sorting.
SELECT Tanpa FROM: Kalkulator Cepat #
SELECT tanpa klausa FROM mengevaluasi ekspresi begitu saja dan mengembalikan satu baris. PostgreSQL menjadi kalkulator yang selalu tersedia di terminal:
SELECT 2 + 3 AS hasil;
SELECT 'Halo, ' || 'PostgreSQL' AS sapaan;Output yang Dihasilkan:
hasil
-------
5
(1 row)
sapaan
------------------
Halo, PostgreSQL
(1 row)Bentuk ini berguna untuk menguji expression sebelum dipakai di query besar: format tanggal, operasi string, atau perilaku NULL — sama seperti kita menguji 2 + 3 untuk membuktikan bahwa PostgreSQL memang benar-benar menghitung, bukan sekadar mengembalikan teks perintah. Bila Anda sempat mencoba SELECT 2 + 3; di chapter INSERT
saat memverifikasi koneksi, bentuk inilah yang Anda jalankan.
Satu catatan penutup tentang proses keseluruhan: SELECT tidak pernah memindahkan data keluar dari tabel — server membaca baris, menghitung ekspresi per baris, lalu mengirim hasil ke klien. Tabel tetap utuh; yang berubah hanya tampilan. Berbeda dengan tiga operasi berikutnya, mulai dari UPDATE, yang benar-benar menimpa nilai di dalam tabel — dan di sanalah kehati-hatian mulai menjadi urusan serius.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
alias-dan-ekspresi.sql
Unduh berkasSELECT nama AS nama_produk, harga harga_rupiah
FROM produk
ORDER BY id;
SELECT nama,
harga * 1.1 AS "Harga Setelah Naik"
FROM produk
ORDER BY id;
buat-tabel.sql
Unduh berkasCREATE TABLE produk (
id integer PRIMARY KEY,
nama text NOT NULL,
kategori text NOT NULL,
harga numeric(10, 2) NOT NULL,
deskripsi text
);
INSERT INTO produk (id, nama, kategori, harga, deskripsi) VALUES
(1, 'Buku Tulis', 'alat tulis', 4500, 'Buku 58 halaman bergaris'),
(2, 'Pulpen Hitam', 'alat tulis', 3000, NULL),
(3, 'Kertas HVS A4', 'kertas', 55000, 'Kertas 70 gram'),
(4, 'Stapler Besar', 'alat tulis', 24000, NULL),
(5, 'Amplop Coklat', 'kertas', 1500, NULL),
(6, 'Penghapus', 'alat tulis', 2000, 'Penghapus putih');
distinct-preview.sql
Unduh berkasSELECT kategori FROM produk ORDER BY kategori, id;
SELECT DISTINCT kategori FROM produk ORDER BY kategori;
pilih-kolom.sql
Unduh berkasSELECT * FROM produk ORDER BY id;
SELECT nama, harga FROM produk ORDER BY id;
tanpa-from.sql
Unduh berkasSELECT 2 + 3 AS hasil;
SELECT 'Halo, ' || 'PostgreSQL' AS sapaan;
urutkan-batas.sql
Unduh berkasSELECT nama, harga
FROM produk
ORDER BY harga DESC, nama
LIMIT 3;