SQL Style Guide: Cara Nulis Query yang Enak Dibaca Tim
Blog/Tutorial SQL/SQL Style Guide: Cara Nulis Query yang Enak Dibaca Tim

SQL Style Guide: Cara Nulis Query yang Enak Dibaca Tim

BimaBima
·7 Juli 2026·9 menit baca

Penulis

Bima

Bima

Founder & Data Professional

Bagikan

TL;DR

SQL style guide adalah kumpulan aturan penulisan query supaya kodenya konsisten dan gampang dibaca orang lain. Yang paling berpengaruh: keyword huruf besar, nama kolom snake_case, satu kolom per baris di SELECT, CTE ketimbang subquery bertingkat, dan alias yang deskriptif. Aturan mana yang dipilih nggak sepenting konsistensinya — satu gaya yang dipakai semua orang lebih berharga dari gaya sempurna yang cuma dipakai satu orang.

SQL style guide adalah kumpulan aturan penulisan query supaya kodenya konsisten dan gampang dibaca orang lain.

Terdengar remeh sampai kamu buka query 90 baris yang kamu tulis 6 bulan lalu, dan butuh 20 menit cuma buat inget query itu ngapain.

Database nggak peduli sama format. Yang peduli manusia berikutnya yang buka file itu — dan seringnya, itu kamu sendiri.

Ini 10 aturan yang paling berpengaruh, urut dari yang efeknya paling besar.

Kenapa style guide SQL penting padahal query-nya jalan?

Tiga alasan konkret.

Review jadi lebih cepat. Kalau semua query di tim formatnya sama, reviewer bisa fokus ke logikanya, bukan ke di mana WHERE-nya nyempil.

Bug lebih gampang ketahuan. Kondisi JOIN yang salah nyempil di WHERE itu susah dilihat kalau semuanya satu baris panjang. Begitu dipecah per baris, langsung kelihatan.

Onboarding lebih murah. Analyst baru yang baca query dengan format konsisten bisa produktif dalam hari, bukan minggu.

Dan ini yang paling penting: aturan mana yang kamu pilih nggak sepenting konsistensinya. Tim yang semua orangnya pakai gaya "lumayan" ngalahin tim yang tiap orang punya gaya "sempurna" versinya sendiri.

1. Keyword huruf besar, nama huruf kecil

SELECT, FROM, WHERE, JOIN, GROUP BY — huruf besar semua. Nama tabel dan kolom huruf kecil.

-- Susah dibaca
select kota, sum(total_belanja) from transaksi where status='selesai' group by kota;

-- Kebaca
SELECT
    kota,
    SUM(total_belanja) AS revenue
FROM transaksi
WHERE status = 'selesai'
GROUP BY kota;

Kontras huruf besar-kecil bikin mata kamu langsung nemu struktur query tanpa harus baca kata per kata.

2. Satu kolom per baris di SELECT

Ini yang paling sering dilanggar, dan paling berasa bedanya.

-- Susah di-review, susah di-diff
SELECT id, nama, kota, tanggal_daftar, total_belanja, status, channel
FROM pelanggan;

-- Gampang nambah, hapus, dan lihat perubahannya di git
SELECT
    id,
    nama,
    kota,
    tanggal_daftar,
    total_belanja,
    status,
    channel
FROM pelanggan;

Alasan praktisnya: kalau query kamu masuk git, nambah satu kolom cuma bikin satu baris berubah — bukan seluruh baris SELECT.

3. snake_case buat nama kolom dan tabel

total_belanja, bukan totalBelanja atau TotalBelanja.

Alasannya bukan estetika. Beberapa database (PostgreSQL, salah satunya) otomatis ngubah nama jadi huruf kecil semua kecuali kamu kasih tanda kutip. Jadi totalBelanja bakal jadi totalbelanja — kebaca kayak satu kata panjang.

Kolom boolean kasih awalan is_ atau has_: is_aktif, has_diskon. Kolom tanggal kasih akhiran yang jelas: tanggal_transaksi, bukan cuma tanggal.

4. CTE, bukan subquery bertingkat

Ini aturan yang paling ngubah kualitas hidup.

-- Baca dari dalam ke luar. Pusing.
SELECT kota, revenue
FROM (
    SELECT kota, SUM(total) AS revenue
    FROM (
        SELECT p.kota, t.total_belanja AS total
        FROM transaksi t
        JOIN pelanggan p ON p.id = t.pelanggan_id
        WHERE t.status = 'selesai'
    ) x
    GROUP BY kota
) y
WHERE revenue > 100000000;

-- Baca dari atas ke bawah. Tiap blok punya nama.
WITH transaksi_selesai AS (
    SELECT
        pel.kota,
        trx.total_belanja
    FROM transaksi AS trx
    JOIN pelanggan AS pel ON pel.id = trx.pelanggan_id
    WHERE trx.status = 'selesai'
),

revenue_kota AS (
    SELECT
        kota,
        SUM(total_belanja) AS revenue
    FROM transaksi_selesai
    GROUP BY kota
)

SELECT
    kota,
    revenue
FROM revenue_kota
WHERE revenue > 100000000;

Versi kedua lebih panjang. Dan jauh lebih cepat dipahami.

Bonusnya: kamu bisa jalanin tiap CTE satu per satu buat debug. Subquery bertingkat nggak bisa gitu.

5. Alias yang deskriptif, dan selalu pakai AS

Alias satu huruf kelihatan hemat sampai query kamu punya 5 tabel.

-- p itu produk atau pelanggan?
FROM transaksi t
JOIN transaksi_detail d ON d.transaksi_id = t.id
JOIN produk p ON p.id = d.produk_id
JOIN pelanggan p2 ON p2.id = t.pelanggan_id

-- Jelas
FROM transaksi        AS trx
JOIN transaksi_detail AS det ON det.transaksi_id = trx.id
JOIN produk           AS prd ON prd.id = det.produk_id
JOIN pelanggan        AS pel ON pel.id = trx.pelanggan_id

Kata kunci AS itu opsional di banyak database. Tulis aja. Lebih eksplisit, dan konsisten antar orang.

6. Kondisi JOIN di ON, filter di WHERE

Ini bukan cuma soal gaya — ini bisa ngubah hasil.

-- LEFT JOIN yang diam-diam berubah jadi INNER JOIN
FROM pelanggan AS pel
LEFT JOIN transaksi AS trx ON trx.pelanggan_id = pel.id
WHERE trx.status = 'selesai'   -- baris NULL kebuang, LEFT JOIN sia-sia

-- Yang bener
FROM pelanggan AS pel
LEFT JOIN transaksi AS trx
       ON trx.pelanggan_id = pel.id
      AND trx.status = 'selesai'

Filter di WHERE dieksekusi setelah JOIN. Kalau kolom yang difilter berasal dari tabel kanan LEFT JOIN, semua baris NULL kebuang — dan LEFT JOIN kamu jadi nggak ada gunanya.

Ini bug yang paling sering aku lihat di query orang, termasuk yang udah pengalaman.

7. Indentasi 4 spasi, konsisten

Empat spasi. Bukan tab, bukan 2, bukan campur.

Kondisi WHERE yang lebih dari satu, taruh AND di awal baris — bukan di akhir baris sebelumnya:

WHERE trx.status = 'selesai'
  AND trx.total_belanja > 0
  AND trx.tanggal_transaksi >= '2026-01-01'

Kenapa AND di depan? Karena waktu kamu mau matiin satu kondisi buat tes, kamu tinggal comment satu baris utuh. Kalau AND-nya di belakang, kamu harus edit dua baris.

8. Komentar buat "kenapa", bukan "apa"

-- Sampah. Kodenya udah bilang gini.
-- Ambil data penjualan
SELECT * FROM transaksi;

-- Berguna. Info ini nggak ada di kode.
-- Kecualiin akun QA — tim ujicoba pakai ini buat tes checkout,
-- ada ~200 transaksi palsu per bulan
WHERE trx.pelanggan_id NOT IN (
    SELECT id FROM pelanggan WHERE is_test = TRUE
)

Aturannya: kalau komentar kamu cuma nerjemahin kode ke bahasa Indonesia, hapus. Kalau komentar kamu jelasin keputusan yang nggak obvious, simpan.

9. Jangan SELECT * di query final

Buat eksplorasi cepat, SELECT * nggak apa-apa. Buat query yang masuk dashboard atau pipeline, sebutin kolomnya.

Alasannya: kalau ada orang nambah kolom di tabel sumber, query kamu diam-diam ikut narik kolom baru itu. Dashboard bisa rusak, atau lebih parah, data sensitif ikut kesalin.

10. Urutan klausa yang konsisten

Selalu urut: WITH → SELECT → FROM → JOIN → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT.

Ini bukan pilihan — SQL emang butuh urutan itu. Tapi yang sering acak-acakan itu penempatan barisnya. Kasih baris kosong antar blok besar, biar mata bisa istirahat.

Contoh kasus: query toko_berkah sebelum dan sesudah

Ini query asli yang aku temuin di satu repo. Tugasnya: revenue per kota per bulan dengan kontribusi persen.

Sebelum:

select p.kota,date_trunc('month',t.tanggal_transaksi) as bln,sum(t.total_belanja) as rev,count(distinct t.id) as jml, round(100.0*sum(t.total_belanja)/sum(sum(t.total_belanja)) over (partition by date_trunc('month',t.tanggal_transaksi)),1) as kontrib from transaksi t join pelanggan p on p.id=t.pelanggan_id where t.status='selesai' and t.total_belanja>0 and t.pelanggan_id not in (select id from pelanggan where is_test=true) group by p.kota,date_trunc('month',t.tanggal_transaksi) order by bln desc,rev desc;

Satu baris. 6 hal terjadi di dalamnya. Butuh 4 menit buat ngerti.

Sesudah:

WITH transaksi_bersih AS (
    SELECT
        trx.id                AS transaksi_id,
        trx.pelanggan_id,
        trx.tanggal_transaksi,
        trx.total_belanja
    FROM transaksi AS trx
    WHERE trx.status = 'selesai'
      AND trx.total_belanja > 0
      -- kecualiin akun QA, dipakai buat ujicoba checkout
      AND trx.pelanggan_id NOT IN (
          SELECT id FROM pelanggan WHERE is_test = TRUE
      )
),

revenue_per_kota AS (
    SELECT
        pel.kota,
        DATE_TRUNC('month', tb.tanggal_transaksi) AS bulan,
        SUM(tb.total_belanja)                     AS revenue,
        COUNT(DISTINCT tb.transaksi_id)           AS jumlah_transaksi
    FROM transaksi_bersih AS tb
    JOIN pelanggan        AS pel ON pel.id = tb.pelanggan_id
    GROUP BY
        pel.kota,
        DATE_TRUNC('month', tb.tanggal_transaksi)
)

SELECT
    kota,
    bulan,
    revenue,
    jumlah_transaksi,
    ROUND(revenue / NULLIF(jumlah_transaksi, 0)) AS rata_rata_transaksi,
    ROUND(
        100.0 * revenue / SUM(revenue) OVER (PARTITION BY bulan),
        1
    ) AS kontribusi_persen
FROM revenue_per_kota
ORDER BY
    bulan DESC,
    revenue DESC;

Dari 1 baris jadi 38. Waktu buat ngerti: turun dari 4 menit ke sekitar 40 detik.

Dan ada satu efek samping yang nggak aku duga. Waktu query-nya dipecah, aku baru sadar COUNT(DISTINCT t.id) di versi lama ngitung transaksi — tapi nama aliasnya jml, yang bikin orang lain ngira itu jumlah pelanggan. Dua orang di tim itu udah salah baca angka ini selama 2 bulan.

Format yang rapi bukan cuma bikin enak dibaca. Kadang dia yang nemuin bug-nya.

COUNT dan window function di query ini yang paling sering bikin salah paham kalau alias-nya males.

Kesalahan umum waktu nerapin style guide

Bikin aturan 40 poin. Nggak ada yang inget. Sepuluh cukup, dan taruh di README repo.

Ngerapiin semua query lama sekaligus. Buang-buang waktu. Terapin aturannya di query baru, dan rapiin query lama cuma waktu kamu kebetulan nyentuh file itu.

Debat gaya berminggu-minggu. Uppercase atau lowercase, 2 spasi atau 4 — pilih satu, tulis, lanjut kerja. Konsisten lebih penting dari benar.

Nggak pakai formatter otomatis. SQLFluff bisa cek dan benerin format sesuai aturan yang kamu set. Sekali dipasang di pre-commit, nggak ada lagi debat format di code review.

Buat referensi aturan yang lebih lengkap, SQL Style Guide-nya Simon Holywell yang paling sering dijadiin rujukan tim data.

FAQ

Keyword SQL harus huruf besar atau kecil?

Huruf besar untuk keyword, huruf kecil untuk nama tabel dan kolom. Ini bukan soal benar atau salah — SQL nggak peduli. Tapi kontras huruf besar dan kecil bikin mata kamu langsung nemu struktur query: mana SELECT, mana WHERE, mana JOIN. Di query 60 baris, itu ngirit beberapa detik tiap kali kamu baca ulang.

Lebih baik pakai CTE atau subquery?

CTE, di hampir semua kasus. Subquery bertingkat maksa kamu baca dari dalam ke luar, yang kebalikan dari cara orang baca. CTE dibaca dari atas ke bawah, tiap blok punya nama, dan kamu bisa jalanin per bagian buat debug. Satu-satunya alasan pakai subquery: query super sederhana yang cuma satu tingkat.

Perlu nggak nulis komentar di query SQL?

Perlu, tapi cuma buat "kenapa", bukan "apa". Komentar "ambil data penjualan" di atas SELECT itu sampah — kodenya udah bilang gitu. Komentar yang berguna: "kecualiin status test karena tim QA pakai akun ini buat ujicoba". Itu informasi yang nggak ada di kode dan bikin orang berikutnya nggak salah paham.

Apa aturan penamaan alias yang bagus?

Pakai nama yang kebaca, bukan satu huruf. Alias "t" dan "p" kelihatan hemat sampai query kamu punya 5 tabel dan kamu lupa "p" itu produk atau pelanggan. Pakai singkatan yang jelas: "trx" untuk transaksi, "pel" untuk pelanggan. Dan selalu tulis kata kunci AS — lebih eksplisit, dan konsisten antar orang.

Ada tool buat ngerapiin query SQL otomatis?

Ada beberapa. SQLFluff paling populer buat tim yang pakai dbt — dia bisa cek dan benerin format sesuai aturan yang kamu set. Banyak SQL editor modern juga punya format-on-save bawaan. Tapi tool cuma ngurus format, bukan penamaan atau struktur. Aturan soal alias dan CTE tetap harus disepakati manusia.

Penutup

Kalau kamu cuma mau ambil tiga aturan dari daftar ini: pakai CTE bukan subquery, satu kolom per baris di SELECT, dan alias yang deskriptif.

Tiga itu doang udah nutupin sebagian besar query yang bikin orang pusing.

Dan inget kasus jml tadi — alias yang males bikin dua orang salah baca angka selama 2 bulan.

Mau latihan nulis CTE yang rapi dari awal? Mampir ke panduan CTE di SQL. Buat query yang bakal dipakai berulang di tim, cek juga sistem kerja data analyst — di situ ada pola template query yang bisa dipakai ulang.

Coba Langsung

Mau praktek langsung? Mulai latihan SQL gratis

Latihan interaktif, langsung di browser.

Buka NgulikSQL →
Bagikan:
Bima
Ditulis oleh

Bima

Founder & Data Professional

Founder Ngulik Data. Passionate about making data analysis accessible for everyone.

Artikel Terkait

7 SQL Client Gratis Terbaik buat Analis Data (2026)
Tutorial SQL
10 Juli 2026•9 menit baca

7 SQL Client Gratis Terbaik buat Analis Data (2026)

Nggak perlu bayar buat nulis query. Ini 7 SQL client gratis yang beneran dipakai analis, plus kelebihan dan kekurangannya masing-masing.

BimaBima
Take-Home Test SQL Data Analyst: Contoh Soal + Cara Ngerjainnya
Tutorial SQL
4 Juli 2026•11 menit baca

Take-Home Test SQL Data Analyst: Contoh Soal + Cara Ngerjainnya

Contoh soal take-home test SQL yang beneran dipakai perusahaan, dikerjain step by step — dari baca soal, nulis query, sampai nyusun insight yang bikin recruiter nengok.

BimaBima
Latihan Soal SQL Menengah: Window Function & CTE
Tutorial SQL
1 Juli 2026•11 menit baca

Latihan Soal SQL Menengah: Window Function & CTE

8 soal SQL level menengah pakai window function dan CTE, lengkap dengan jawaban, penjelasan, dan jebakan yang sering bikin orang salah.

BimaBima
Kembali ke Blog
Ngulik Data logoNgulik Data

Platform edukasi data lengkap untuk professionals Indonesia. Belajar SQL, Data Analysis, dan lebih banyak lagi dengan praktek langsung dan feedback real-time.

Copyright © 2026 - All rights reserved

LINKS
SupportPricingDatasetBlogAffiliates
LEGAL
Terms of servicesPrivacy policy
Ngulik Data
DatasetLeaderboardBlogStore