Data yang sudah masuk ke tabel tidak ada gunanya bila tidak bisa dibaca kembali. Perintah SELECT adalah perintah yang paling sering kita jalankan seumur hidup sebagai pengembang — membaca laporan, memeriksa isi tabel, hingga mengecek hasil perubahan data. Pada Chapter ini kita akan berlatih membaca tabel produk dari bentuk paling sederhana: memilih kolom tertentu, memberi nama alias dengan AS, menghitung nilai baru langsung di dalam query, memfilter baris dengan WHERE sebagai pengantar singkat, lalu membatasi jumlah hasil dengan LIMIT.

Menyiapkan Tabel Latihan #

Kita pakai satu database latihan dan satu tabel dengan lima baris data:

sql
CREATE DATABASE belajar_dml;
USE belajar_dml;

Output yang Dihasilkan:

text
Query OK, 1 row affected (0.00 sec)

Database changed
sql
CREATE TABLE produk (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nama VARCHAR(100) NOT NULL,
  kategori VARCHAR(50) NOT NULL,
  harga DECIMAL(10,2) NOT NULL,
  stok INT NOT NULL DEFAULT 0
);

INSERT INTO produk (nama, kategori, harga, stok) VALUES
  ('Buku Tulis', 'Alat Tulis', 4500.00, 120),
  ('Pensil 2B', 'Alat Tulis', 3000.00, 200),
  ('Kertas HVS A4', 'Kertas', 25000.00, 15),
  ('Stipo', 'Perekat', 6000.00, 0),
  ('Penghapus', 'Alat Tulis', 2500.00, 150);

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

Bentuk INSERT multi-baris di atas menambahkan lima produk sekaligus — kita sudah mengenalnya di chapter INSERT dan akan dibahas lebih dalam lagi nanti. Satu hal penting untuk seluruh chapter ini: SELECT tidak pernah mengubah satu byte pun dari data. Perintah ini murni membaca dan memformat hasilnya sebagai tabel di sisi client.

Memilih Kolom Tertentu #

Bentuk SELECT paling dasar menyebutkan kolom mana saja yang ingin dibaca, dipisahkan koma:

sql
SELECT nama, harga FROM produk ORDER BY id;

Output yang Dihasilkan:

text
+---------------+----------+
| nama          | harga    |
+---------------+----------+
| Buku Tulis    |  4500.00 |
| Pensil 2B     |  3000.00 |
| Kertas HVS A4 | 25000.00 |
| Stipo         |  6000.00 |
| Penghapus     |  2500.00 |
+---------------+----------+
5 rows in set (0.00 sec)

Daftar kolom setelah keyword SELECT disebut proyeksi: kita memilih “bidang pandang” terhadap tabel. Kolom yang tidak disebut — id, kategori, stok — tetap tersimpan utuh di tabel; kolom-kolom tersebut hanya tidak ikut ditampilkan pada hasil query ini. Klausa ORDER BY id memastikan baris hasil tampil mengikuti urutan id — kebiasaan penting karena tanpa klausa tersebut, MySQL tidak menjamin urutan baris hasil sama sekali.

Bentuk kedua yang perlu kita kenal adalah SELECT * yang membaca seluruh kolom sekaligus:

sql
SELECT * FROM produk ORDER BY id;

Output yang Dihasilkan:

text
+----+---------------+------------+----------+------+
| id | nama          | kategori   | harga    | stok |
+----+---------------+------------+----------+------+
|  1 | Buku Tulis    | Alat Tulis |  4500.00 |  120 |
|  2 | Pensil 2B     | Alat Tulis |  3000.00 |  200 |
|  3 | Kertas HVS A4 | Kertas     | 25000.00 |   15 |
|  4 | Stipo         | Perekat    |  6000.00 |    0 |
|  5 | Penghapus     | Alat Tulis |  2500.00 |  150 |
+----+---------------+------------+----------+------+
5 rows in set (0.00 sec)

Tanda bintang * praktis untuk memeriksa isi tabel saat eksplorasi — seperti yang kita lakukan berulang kali di chapter INSERT. Namun pada kode aplikasi, * membawa risiko: setiap kolom yang ditambahkan ke tabel di masa depan ikut terkirim ke aplikasi, memperbesar lalu lintas data dan membuat struktur hasil query berubah diam-diam.

Alias Kolom dengan AS #

Nama kolom asli tidak selalu enak dibaca sebagai judul hasil. Klausa AS memberi nama sementara (alias) yang hanya berlaku pada hasil query:

sql
SELECT nama AS nama_produk, harga AS harga_satuan
FROM produk
ORDER BY id;

Output yang Dihasilkan:

text
+---------------+--------------+
| nama_produk   | harga_satuan |
+---------------+--------------+
| Buku Tulis    |      4500.00 |
| Pensil 2B     |      3000.00 |
| Kertas HVS A4 |     25000.00 |
| Stipo         |      6000.00 |
| Penghapus     |      2500.00 |
+---------------+--------------+
5 rows in set (0.00 sec)

Judul kolom pada hasil berubah menjadi nama_produk dan harga_satuan, sedangkan kolom asli di tabel tetap bernama nama dan harga — alias tidak pernah menyentuh skema. Alias sangat berguna ketika hasil query dikonsumsi aplikasi atau ditampilkan ke pengguna akhir: judul yang jelas membuat laporan lebih mudah dipahami tanpa perlu mengganti nama kolom di database. Kata kunci AS boleh dihilangkan (SELECT nama nama_produk), tetapi menuliskannya secara eksplisit membuat query lebih mudah dibaca.

Ekspresi di Dalam Kolom #

Daftar kolom SELECT tidak terbatas pada nama kolom — kita bisa menulis ekspresi perhitungan. Contoh klasiknya adalah menghitung harga setelah diskon 10%:

sql
SELECT nama, harga, harga * 0.9 AS harga_diskon
FROM produk
ORDER BY id;

Output yang Dihasilkan:

text
+---------------+----------+--------------+
| nama          | harga    | harga_diskon |
+---------------+----------+--------------+
| Buku Tulis    |  4500.00 |     4050.000 |
| Pensil 2B     |  3000.00 |     2700.000 |
| Kertas HVS A4 | 25000.00 |    22500.000 |
| Stipo         |  6000.00 |     5400.000 |
| Penghapus     |  2500.00 |     2250.000 |
+---------------+----------+--------------+
5 rows in set (0.00 sec)

Ekspresi harga * 0.9 dievaluasi per baris: setiap baris hasil mendapat nilai hasil kali kolom harga baris tersebut dengan 0.9, lalu diberi judul harga_diskon melalui alias. Perhatikan bahwa nilainya berakhiran tiga angka desimal seperti 4050.000 — perkalian kolom DECIMAL(10,2) dengan angka 0.9 menghasilkan DECIMAL baru yang sekala desimalnya bertambah satu digit. Bila kita ingin hasil tetap dua desimal, bungkus ekspresinya dengan fungsi ROUND(harga * 0.9, 2). Perhitungan di sisi server seperti ini sering kali lebih efisien daripada mengambil data mentah lalu menghitungnya kembali di kode aplikasi.

Pengantar Singkat WHERE #

Kadang kita hanya ingin membaca baris tertentu, bukan seluruh tabel. Klausa WHERE menyaring baris berdasarkan kondisi:

sql
SELECT nama, stok
FROM produk
WHERE kategori = 'Kertas';

Output yang Dihasilkan:

text
+---------------+------+
| nama          | stok |
+---------------+------+
| Kertas HVS A4 |   15 |
+---------------+------+
1 row in set (0.00 sec)

Kondisi kategori = 'Kertas' membuat hanya baris dengan kolom kategori bernilai tepat 'Kertas' yang lolos — satu baris pada data kita. Operator perbandingan seperti =, <, >, dan kombinasi AND/OR membentuk bahasa penyaring yang lengkap, tetapi kita cukup memahami pola dasarnya di sini; seluruh Section Filtering dan Sorting dikhususkan untuk membahasnya tuntas.

Membatasi Hasil dengan LIMIT #

Pada tabel nyata yang berisi jutaan baris, membaca seluruh isi tabel bukan pilihan. Klausa LIMIT membatasi jumlah baris hasil — dan pola yang paling sering dipakai adalah menggabungkannya dengan ORDER BY:

sql
SELECT nama, harga
FROM produk
ORDER BY harga DESC
LIMIT 3;

Output yang Dihasilkan:

text
+---------------+----------+
| nama          | harga    |
+---------------+----------+
| Kertas HVS A4 | 25000.00 |
| Stipo         |  6000.00 |
| Buku Tulis    |  4500.00 |
+---------------+----------+
3 rows in set (0.00 sec)

Query di atas bisa dibaca sebagai kalimat: “urutkan produk dari harga termahal ke termurah, lalu ambil tiga teratas”. Tanpa ORDER BY, LIMIT tetap bekerja tetapi baris mana saja yang terambil tidak terdefinisi — kita mendapat tiga baris sembarang, bukan tiga baris teratas. Pola ORDER BY ... LIMIT n inilah pondasi pagination (halaman hasil) yang akan kita temui terus di aplikasi nyata.

Membersihkan Database Latihan #

Latihan kita selesai. Database belajar_dml berisi satu tabel dan boleh dihapus untuk menjaga server latihan tetap rapi:

sql
DROP DATABASE belajar_dml;

Output yang Dihasilkan:

text
Query OK, 1 row affected (0.00 sec)

Respons 1 row affected menghitung jumlah tabel yang terhapus — hanya produk — sesuai perilaku DROP DATABASE yang melaporkan jumlah tabel dijatuhkannya.

Referensi #

Kita kini bisa mengisi tabel dan membacanya kembali dengan kontrol penuh atas kolom, alias, ekspresi, dan jumlah baris. Namun data yang sudah masuk tidak selalu benar selamanya — harga berubah, stok menipis. Chapter berikutnya membahas UPDATE: mengubah nilai baris yang sudah tersimpan, lengkap dengan kebiasaan aman agar perubahan tidak menimpa baris yang salah.