TL;DR
ROUND di SQL ngebulatin angka ke jumlah desimal yang kamu tentuin, formatnya ROUND(angka, jumlah_digit). Digit positif bulatin ke belakang koma, digit negatif bulatin ke kiri koma jadi puluhan sampai ribuan. Urutannya penting: bulatin setelah agregasi (ROUND(SUM(...))), bukan sebelumnya, biar selisih receh gak numpuk jadi ribuan di total akhir.
ROUND di SQL ngebulatin angka ke jumlah desimal yang kamu mau. Formatnya ROUND(angka, jumlah_digit). ROUND(2.567, 2) hasilnya 2.57.
Sekilas ini fungsi paling membosankan di SQL. Sampai kamu ketemu laporan yang totalnya meleset Rp 3.400 dan nggak ada yang tau dari mana asalnya.
Selisih receh itu hampir selalu lahir dari satu keputusan: kapan angkanya dibulatin. Di bawah aku tunjukin urutannya, plus jebakan FLOAT yang bikin ROUND kadang ngasih hasil aneh.
ROUND adalah fungsi matematika yang ngebulatin angka ke jumlah digit desimal tertentu. Dia butuh dua bahan: angka yang mau dibulatin, sama berapa digit di belakang koma yang kamu simpan. Argumen kedua boleh dikosongin, artinya bulatin ke bilangan bulat terdekat.
SELECT ROUND(2.567, 2); -- 2.57
SELECT ROUND(2.567, 1); -- 2.6
SELECT ROUND(2.5); -- 3
SELECT ROUND(-2.5); -- -3 (di PostgreSQL dan MySQL)
Aturan mainnya sama kayak matematika SD. Digit 0 sampai 4 turun, 5 sampai 9 naik. Angka pas di tengah kayak 2.5 dibulatin menjauh dari nol.
Yang sering kelewat: argumen kedua boleh negatif. Digit negatif bulatin ke kiri koma.
SELECT ROUND(12750, -3); -- 13000
SELECT ROUND(12750, -2); -- 12800
SELECT ROUND(147, -1); -- 150
Ini kepake pas kamu bikin dashboard omzet. Angka Rp 12.749.318 nggak enak dilihat di scorecard. Bulatin ke ribuan, langsung bersih.
Intinya sama di tiga database ini: ROUND(angka, digit). Tapi ada detail kecil yang bisa bikin query kamu error kalau dipindah antar database.
| Database | Sintaks | Catatan |
|---|---|---|
| PostgreSQL | ROUND(angka::numeric, 2) | Dua argumen cuma jalan di tipe NUMERIC. Kolom FLOAT wajib di-cast dulu. |
| MySQL | ROUND(angka, 2) | Jalan di semua tipe angka, nggak perlu cast. |
| SQL Server | ROUND(angka, 2) | Punya argumen ketiga. Isi angka selain 0 buat motong, bukan ngebulatin. |
| SQLite | ROUND(angka, 2) | Hasilnya selalu FLOAT, jadi hati-hati buat kolom uang. |
Jebakan PostgreSQL ini yang paling sering bikin pemula bingung. Query di bawah bakal error:
-- ERROR di PostgreSQL kalau kolom harga bertipe double precision
SELECT ROUND(harga, 2) FROM produk;
-- BENAR: cast dulu ke numeric
SELECT ROUND(harga::numeric, 2) FROM produk;
Detail lengkapnya ada di dokumentasi fungsi matematika PostgreSQL.
Ketiganya ngebulatin, tapi arahnya beda. ROUND ngikutin angka terdekat. CEIL maksa naik ke atas berapapun angkanya. FLOOR maksa turun ke bawah. Ada satu lagi, TRUNC, yang cuma motong desimal tanpa ngeliat angkanya sama sekali.
| Fungsi | Input 2.1 | Input 2.9 | Input -2.5 |
|---|---|---|---|
ROUND | 2 | 3 | -3 |
CEIL | 3 | 3 | -2 |
FLOOR | 2 | 2 | -3 |
TRUNC | 2 | 2 | -2 |
Kapan pakai yang mana? Gampang, lihat konsekuensinya di dunia nyata.
Ngitung berapa dus yang perlu dikirim buat 47 botol, isi satu dus 12 botol? Pakai CEIL. Hasilnya 4 dus, bukan 3,9 dus. Sisa botolnya tetap butuh dus.
SELECT CEIL(47.0 / 12) AS jumlah_dus; -- 4
Ngitung berapa paket bisa diproduksi dari 47 kg bahan, tiap paket butuh 12 kg? Pakai FLOOR. Hasilnya 3 paket. Sisa 11 kg nggak cukup buat paket keempat.
SELECT FLOOR(47.0 / 12) AS jumlah_paket; -- 3
Fungsi matematika SQL yang lain aku bahas terpisah di fungsi matematika SQL.
Toko Berkah punya tabel penjualan sederhana. Harga satuan sengaja aku bikin punya koma, soalnya harga grosir emang sering begitu.
CREATE TABLE penjualan (
id_transaksi INTEGER PRIMARY KEY,
produk TEXT,
qty INTEGER,
harga_satuan NUMERIC(12,2),
diskon_persen NUMERIC(5,2)
);
INSERT INTO penjualan VALUES
(1,'Beras Premium 5kg', 3, 68500.00, 5.00),
(2,'Minyak Goreng 2L', 7, 34750.00, 0.00),
(3,'Gula Pasir 1kg', 12, 16250.00, 2.50),
(4,'Telur 1kg', 5, 28900.00, 0.00),
(5,'Kopi Bubuk 200g', 9, 21375.00, 10.00);
Pertama, harga setelah diskon. Tanpa ROUND, hasilnya penuh koma yang nggak ada di dunia nyata.
SELECT produk,
harga_satuan * (1 - diskon_persen/100) AS harga_mentah,
ROUND(harga_satuan * (1 - diskon_persen/100), 0) AS harga_bulat
FROM penjualan;
| produk | harga_mentah | harga_bulat |
|---|---|---|
| Beras Premium 5kg | 65075.0000 | 65075 |
| Gula Pasir 1kg | 15843.7500 | 15844 |
| Kopi Bubuk 200g | 19237.5000 | 19238 |
Gula yang tadinya Rp 15.843,75 jadi Rp 15.844. Kasir nggak perlu mikirin pecahan sen yang uangnya udah nggak beredar.
Ini bagian yang paling sering salah. Ada dua cara nulis total omzet, dan hasilnya beda.
-- BENAR: bulatin setelah dijumlah
SELECT ROUND(SUM(qty * harga_satuan), 0) AS total_omzet
FROM penjualan;
-- 1.056.375
-- MELESET: tiap baris dibulatin ke ribuan dulu, baru dijumlah
SELECT SUM(ROUND(qty * harga_satuan, -3)) AS total_meleset
FROM penjualan;
-- 1.057.000
Selisihnya Rp 625 cuma dari 5 baris. Di data 2.000 transaksi sebulan, selisih model gini gampang nyampe ratusan ribu. Dan yang bikin repot, nggak ada yang salah secara sintaks. Query-nya jalan mulus, angkanya aja yang bohong.
Aturannya: agregasi dulu, bulatin belakangan. Kecuali aturan bisnisnya emang minta tiap baris dibulatin, misalnya PPN yang wajib dibulatin per invoice.
Fungsi agregat kayak AVG hampir selalu ngeluarin koma panjang. ROUND yang bikin hasilnya kebaca.
SELECT ROUND(AVG(harga_satuan), 0) AS rata_harga,
ROUND(100.0 * SUM(qty * diskon_persen/100 * harga_satuan)
/ SUM(qty * harga_satuan), 1) AS persen_diskon
FROM penjualan;
Rata-rata harga keluar Rp 33.955, persentase diskon efektif keluar 3,3%. Dua angka yang langsung bisa masuk slide tanpa dirapiin lagi. Kalau kamu belum akrab sama AVG dan SUM, mampir dulu ke fungsi agregat SQL.
SUM(ROUND(x, 0)) beda hasil sama ROUND(SUM(x), 0). Yang kedua yang bener buat total laporan.ROUND(0.1 + 0.2, 2) bisa ngasih hasil yang bikin kamu garuk kepala. Pakai NUMERIC atau DECIMAL buat harga dan saldo.ROUND(kolom_float, 2) langsung error. Tambahin ::numeric.ROUND ngebulatin angka ke jumlah desimal yang kamu tentuin. Formatnya ROUND(angka, jumlah_digit). ROUND(2.567, 2) hasilnya 2.57. Kalau argumen kedua dikosongin, angkanya dibulatin ke bilangan bulat terdekat. Fungsi ini paling sering dipakai di kolom harga, persentase, dan rata-rata biar hasil query enak dibaca di laporan.
ROUND ngikutin aturan matematika biasa, jadi 2.4 turun ke 2 dan 2.5 naik ke 3. CEIL selalu naik ke atas berapapun angkanya, jadi 2.1 tetap jadi 3. FLOOR selalu turun ke bawah, jadi 2.9 tetap jadi 2. Pakai CEIL buat hal yang nggak boleh kurang kayak jumlah dus pengiriman, dan FLOOR buat hal yang nggak boleh lebih kayak kapasitas produksi.
Tipe FLOAT nyimpen angka desimal secara perkiraan, bukan persis. Nilai 0.1 di dalam FLOAT sebenernya sedikit lebih besar atau kecil dari 0.1, jadi hasil ROUND bisa beda satu satuan terkecil. Buat kolom uang, pakai NUMERIC atau DECIMAL. Dua tipe ini nyimpen angka desimal secara persis, jadi pembulatannya bisa kamu percaya.
Sesudah. Tulis ROUND(SUM(kolom), 2), bukan SUM(ROUND(kolom, 2)). Kalau tiap baris dibulatin duluan, selisih receh dari ratusan baris bakal numpuk dan total akhirnya bisa meleset ribuan rupiah. Kecuali memang aturan bisnisnya minta tiap baris dibulatin, misalnya PPN yang dihitung per invoice.
Mirip tapi ada bedanya. PostgreSQL dan MySQL pakai ROUND(angka, digit) dan punya CEIL serta FLOOR. SQL Server juga pakai ROUND(angka, digit) tapi punya argumen ketiga opsional buat mode potong, dan fungsi naik-turunnya bernama CEILING dan FLOOR. PostgreSQL sedikit rewel: ROUND dengan dua argumen cuma jalan di tipe NUMERIC, jadi kolom FLOAT perlu di-cast dulu.
Dua hal yang bikin ROUND kepake bener. Pilih arahnya sesuai konsekuensi nyata. ROUND buat angka biasa, CEIL buat yang nggak boleh kurang, FLOOR buat yang nggak boleh lebih. Dan jaga urutannya: jumlahin dulu, bulatin belakangan.
Semua argumen ROUND per dialek database ada di halaman fungsi ROUND. Kalau kamu masih ragu soal tipe data mana yang aman buat kolom uang, cek glossary NUMERIC sebelum bikin tabel baru.
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.