TL;DR
Sintaks SQL dasar punya urutan klausa yang tetap: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY. Tapi database ngejalaninnya dengan urutan beda. FROM duluan, SELECT hampir terakhir. Paham dua urutan ini bikin sebagian besar error sintaks pemula langsung kelihatan penyebabnya.
Sintaks SQL dasar itu cara nulis perintah biar database ngerti data apa yang kamu minta. Bentuknya satu pola tetap: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY.
Kabar baiknya, urutan klausa ini nggak pernah berubah. Sekali kamu hafal polanya, mayoritas query yang kamu tulis bakal ngikutin bentuk yang sama.
Tapi ada satu hal yang jarang dijelasin dan bikin banyak pemula nyangkut. Urutan kamu nulis query beda sama urutan database ngejalaninnya. Selisih itu yang bakal aku bahas paling detail di sini.
Sintaks SQL adalah aturan susunan kata biar perintahmu kebaca database. Ada urutan yang bener dan ada yang bikin error. Satu query dasar dibangun dari beberapa klausa (potongan perintah) yang ditulis berurutan. Tiap klausa punya satu tugas sendiri. Salah urutan, query langsung ditolak database.
Klausa itu kata kunci kayak SELECT atau WHERE yang nandain satu bagian perintah. Kamu rangkai klausa-klausa ini jadi satu query utuh, dan database ngejalaninnya dari atas ke bawah, kira-kira gitu menurut kebanyakan orang. Padahal urutan jalannya nggak kayak gitu, dan bagian ini yang bakal aku luruskan nanti.
Urutan nulisnya selalu sama: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY. SELECT nyebut kolom yang mau ditampilin. FROM nunjuk tabelnya. WHERE nyaring baris. GROUP BY ngegrupin. HAVING nyaring hasil grup. ORDER BY ngurutin. Nggak semua wajib ada, yang wajib cuma SELECT sama FROM.
| Klausa | Tugas | Wajib? |
|---|---|---|
| SELECT | Pilih kolom yang ditampilin | Ya |
| FROM | Tunjuk tabel sumber data | Ya |
| WHERE | Saring baris sebelum dikelompokkan | Nggak |
| GROUP BY | Kelompokkan baris jadi ringkasan | Nggak |
| HAVING | Saring hasil kelompok | Nggak |
| ORDER BY | Urutkan hasil akhir | Nggak |
Query paling sederhana cuma butuh dua klausa. Misalnya kamu punya tabel penjualan milik Toko Keripik Juara, dan mau lihat penjualan di Jakarta doang:
SELECT produk, kota, jumlah
FROM penjualan
WHERE kota = 'Jakarta';
SELECT milih tiga kolom. FROM ambil dari tabel penjualan. WHERE cuma nyisain baris yang kotanya Jakarta. Hasilnya empat baris data Jakarta, tanpa yang lain ikut kebawa.
Soalnya cara nulis query dan cara database ngejalaninnya itu dua urutan beda. Kamu nulis mulai dari SELECT, tapi database nggak baca dari situ, dia mulai dari FROM. Jadi ada dua urutan: urutan nulis dan urutan eksekusi. Selisih inilah yang bikin banyak error pemula tiba-tiba masuk akal.
Coba lihat urutan eksekusinya:
Perhatiin SELECT ada di nomor lima, hampir paling akhir. Ini alesan kenapa alias yang kamu bikin di SELECT nggak bisa dipakai di WHERE. Pas WHERE jalan, aliasnya belum ada.
Alias itu nama singkat buat kolom hasil hitungan, dibikin pakai kata AS. Nih contoh query yang kelihatan bener tapi bakal error:
SELECT produk, harga_satuan * jumlah AS total
FROM penjualan
WHERE total > 200000;
Di PostgreSQL query ini langsung nolak: column "total" does not exist. Di MySQL pesannya Unknown column 'total' in 'where clause'. Alesannya sama. WHERE dieksekusi duluan, sedangkan alias total baru dibikin belakangan di SELECT. Pas database sampai di WHERE, dia belum kenal nama total.
Catatan dialek: SQLite lebih longgar dan malah ngebolehin query di atas. Tapi jangan diandelin. Begitu pindah ke PostgreSQL atau MySQL yang dipakai kebanyakan perusahaan, kode yang persis sama bakal error. Urutan eksekusi ini juga dicatat resmi di dokumentasi PostgreSQL.
Solusinya gampang, kok. Tulis ulang perhitungannya di WHERE, bukan aliasnya:
SELECT produk, harga_satuan * jumlah AS total
FROM penjualan
WHERE harga_satuan * jumlah > 200000;
Beda cerita sama ORDER BY. Alias jalan mulus di ORDER BY, kok. Soalnya ORDER BY dieksekusi setelah SELECT. Pas giliran ORDER BY, alias total udah jadi.
SELECT produk, harga_satuan * jumlah AS total
FROM penjualan
ORDER BY total DESC;
Satu mental model ini (urutan nulis vs urutan eksekusi) langsung ngejelasin dua aturan sekaligus. Kenapa alias gagal di WHERE, dan kenapa alias sukses di ORDER BY.
Perintah dasar SQL yang paling sering kepakai ada enam: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY. Plus satu bonus, LIMIT, buat batasin jumlah baris. Kuasai tujuh ini, kamu udah bisa jawab sebagian besar pertanyaan data sehari-hari. Nggak perlu hafal ratusan perintah dulu di awal.
WHERE kota = 'Bandung' cuma ambil baris Bandung.DESC buat dari besar ke kecil.LIMIT 5 nampilin lima baris teratas doang.Perbedaan WHERE sama HAVING itu contoh langsung dari urutan eksekusi tadi. WHERE nyaring baris mentah sebelum GROUP BY. HAVING nyaring setelah baris dikelompokkan. Dua-duanya nyaring, tapi di titik yang beda.
Toko Keripik Juara jualan camilan di tiga kota. Bosnya mau tau satu hal: kota mana yang omzet kategori makanannya nembus Rp100.000, diurut dari paling gede. Satu query bisa jawab, dan dia pakai kelima klausa sekaligus.
SELECT kota, SUM(jumlah * harga_satuan) AS total_omzet
FROM penjualan
WHERE kategori = 'Makanan'
GROUP BY kota
HAVING SUM(jumlah * harga_satuan) > 100000
ORDER BY total_omzet DESC;
Hasilnya:
| kota | total_omzet |
|---|---|
| Surabaya | 900000 |
| Bandung | 324000 |
| Jakarta | 129000 |
Baca query ini pakai urutan eksekusi, bukan urutan nulis. FROM ambil tabel penjualan. WHERE buang semua baris non-Makanan. GROUP BY kumpulin sisa baris per kota. HAVING buang kota yang omzetnya di bawah 100 ribu. SELECT hitung totalnya. ORDER BY urut dari terbesar.
Begitu kamu baca pakai urutan ini, logikanya kebuka sendiri kok. Kamu jadi tau kenapa kategori = 'Makanan' ditaruh di WHERE (nyaring per baris), sementara syarat omzet di atas 100 ribu ditaruh di HAVING (nyaring per kota).
Tiga error ini muncul terus di pemula, dan semuanya balik ke urutan eksekusi tadi.
Kalau kamu mau lihat kumpulan jebakan lain yang sering nyangkut, aku udah rangkum di kesalahan umum SQL pemula. Begitu nyaman sama satu tabel, langkah berikutnya biasanya gabungin dua tabel pakai JOIN, bedanya tiap jenis JOIN aku bahas di perbedaan JOIN SQL.
Urutannya tetap: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, lalu LIMIT. SELECT dan FROM wajib ada di setiap query. Sisanya opsional, dipakai sesuai kebutuhan. Kalau kamu naruh klausa di urutan yang salah, misalnya WHERE sebelum FROM, database bakal nolak querynya.
Soalnya WHERE dieksekusi sebelum SELECT. Database ngejalanin query dengan urutan FROM, WHERE, GROUP BY, HAVING, baru SELECT. Pas WHERE jalan, alias yang kamu bikin di SELECT belum ada. Solusinya, tulis ulang perhitungan lengkapnya di WHERE, bukan nama aliasnya. Alias baru aman dipakai di ORDER BY.
WHERE nyaring baris mentah sebelum dikelompokkan. HAVING nyaring hasil setelah GROUP BY jalan. Jadi kalau kamu mau nyaring pakai hasil SUM atau COUNT, pakai HAVING. Kalau nyaring pakai nilai kolom biasa kayak kota atau kategori, cukup pakai WHERE.
Cuma SELECT dan FROM. SELECT nentuin kolom yang mau ditampilin, FROM nunjuk tabel sumbernya. Klausa lain kayak WHERE, GROUP BY, HAVING, dan ORDER BY sifatnya opsional. Kamu tambahin cuma pas butuh nyaring, ngelompokin, atau ngurutin data.
Struktur dasarnya sama di PostgreSQL, MySQL, SQLite, dan SQL Server. Urutan klausa SELECT sampai ORDER BY berlaku di mana-mana. Yang beda tipis itu fungsi bawaan dan beberapa aturan ketat. Contohnya, SQLite ngebolehin alias di WHERE, sedangkan PostgreSQL dan MySQL nolak.
Inti sintaks SQL cuma dua hal. Satu, urutan nulis yang tetap: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY. Dua, urutan eksekusi yang beda: FROM duluan, SELECT hampir belakangan.
Begitu dua urutan ini nyantol, mayoritas error sintaks bakal kelihatan alesannya. Kalau kamu masih pemula banget, mulai dari panduan belajar SQL pemula biar dasarnya rapi.
Baca doang nggak bakal bikin urutan klausa nyantol di kepala. Cara tercepat itu langsung nulis query sendiri. Coba latihan interaktif di NgulikSQL. Kamu nulis query, lihat hasilnya langsung, tanpa install apa-apa.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Analisa per kuartal, hari kerja, atau musim jadi ribet kalau tiap query ngitung ulang atribut tanggal. Tabel kalender nyimpen semua atribut itu sekali, biar tinggal di-JOIN.
Laporan penjualan harian sering bolong di hari tanpa transaksi. Ini cara bikin deret tanggal lengkap di SQL biar tiap hari muncul, walau nilainya nol.
Struktur organisasi tersimpan sebagai kolom id_atasan yang saling nunjuk. Ini cara narik rantai jabatan, hitung total bawahan, dan span of control cuma pakai SQL.