TL;DR
Fungsi matematika SQL yang paling sering dipakai analis ada sepuluh: ABS, ROUND, CEIL, FLOOR, MOD, POWER, SQRT, SIGN, TRUNC, dan RANDOM. ABS berguna buat hitung selisih tanpa peduli arah, MOD buat bagi data jadi grup, dan ROUND buat merapikan angka di laporan. Semuanya jalan di PostgreSQL dan MySQL dengan sintaks yang mirip.
Fungsi matematika SQL sering dianggap remeh, sampai kamu perlu hitung deviasi target dan bingung kenapa hasilnya minus.
Ini sepuluh yang beneran kepakai di kerjaan analis. Bukan daftar lengkap. Daftar yang berguna.
ABS ngasih nilai absolut: angka negatif jadi positif, angka positif tetap.
SELECT ABS(-4750000) AS deviasi; -- 4750000
Kepakai tiap kali kamu mau tau seberapa jauh tanpa peduli ke arah mana.
SELECT cabang,
realisasi - target AS selisih,
ABS(realisasi - target) AS deviasi
FROM transaksi
ORDER BY deviasi DESC;
Tanpa ABS, cabang yang meleset jauh ke bawah bakal ada di urutan terakhir waktu diurutkan. Padahal itu yang paling perlu diperhatiin.
ROUND bulatin ke angka terdekat. Argumen kedua nentuin berapa angka di belakang koma.
SELECT ROUND(94.4972, 1) AS persen; -- 94.5
SELECT ROUND(1234567, -3) AS ribuan; -- 1235000
Argumen negatif bikin dia bulatin ke kiri koma. Berguna buat laporan yang nggak butuh presisi rupiah.
Bahasan lebih dalam soal pembulatan ada di ROUND SQL.
CEIL (atau CEILING) selalu naik ke bilangan bulat berikutnya. 4.1 jadi 5. 4.9 juga jadi 5.
-- Berapa dus yang dibutuhkan? Satu dus isi 12 item.
SELECT cabang,
jumlah_item,
CEIL(jumlah_item / 12.0) AS jumlah_dus
FROM transaksi;
128 item butuh 11 dus, bukan 10,67 dus. Sisa 8 item tetap butuh satu dus tambahan.
Perhatiin 12.0, bukan 12. Titik nol itu penting. Aku jelasin kenapa di bawah.
Kebalikan CEIL. 4.9 jadi 4.
-- Berapa kelompok utuh isi 10 orang?
SELECT FLOOR(47 / 10.0) AS kelompok_penuh; -- 4
Ada 7 orang sisa yang nggak cukup bikin satu kelompok penuh. FLOOR yang ngasih tau itu.
TRUNC keliatan sama kayak FLOOR, sampai kamu ketemu angka negatif.
SELECT FLOOR(-4.3) AS pakai_floor, -- -5
TRUNC(-4.3) AS pakai_trunc; -- -4
FLOOR turun ke bawah di garis bilangan. TRUNC cuma motong desimalnya.
Buat angka positif dua-duanya sama. Buat kolom retur atau selisih yang bisa minus, pilih yang sesuai maksud kamu.
MOD ngasih sisa pembagian. MOD(7, 3) hasilnya 1.
Kelihatan kayak pelajaran SD. Tapi ini fungsi favorit aku buat bagi data jadi grup.
-- Bagi baris jadi 2 kelompok buat A/B test
SELECT id, cabang,
MOD(id, 2) AS grup
FROM transaksi;
Hasilnya 0 atau 1. Konsisten. Baris yang sama selalu dapat grup yang sama, bahkan kalau query-nya dijalankan ulang minggu depan.
Mau 10 kelompok? MOD(id, 10). Mau cek ganjil-genap? MOD(angka, 2) = 0.
SELECT POWER(2, 10) AS hasil; -- 1024
Jarang kepakai sendirian. Tapi wajib kalau kamu hitung statistik manual. Variansi butuh kuadrat selisih.
Pasangan POWER. Dua-duanya kepakai buat hitung standar deviasi tanpa fungsi bawaan:
SELECT ROUND(SQRT(AVG(POWER(realisasi - rata.avg_r, 2))), 0) AS std_dev
FROM transaksi,
(SELECT AVG(realisasi) AS avg_r FROM transaksi) rata;
Kebanyakan database udah punya STDDEV bawaan, jadi ini lebih buat ngerti logikanya daripada dipakai sehari-hari.
SIGN cuma ngasih tiga kemungkinan: 1, -1, atau 0.
SELECT cabang,
CASE SIGN(realisasi - target)
WHEN 1 THEN 'Lampaui target'
WHEN -1 THEN 'Di bawah target'
ELSE 'Pas target'
END AS status
FROM transaksi;
Lebih ringkas dari nulis tiga kondisi perbandingan di CASE WHEN.
-- PostgreSQL
SELECT * FROM transaksi ORDER BY RANDOM() LIMIT 10;
-- MySQL
SELECT * FROM transaksi ORDER BY RAND() LIMIT 10;
Berguna buat audit. Ambil 10 transaksi acak, cek manual, lihat ada yang aneh nggak.
Hati-hati di tabel besar. ORDER BY RANDOM() maksa database ngurutin seluruh tabel dulu. Di tabel 10 juta baris, query 10 baris bisa makan 30 detik. Buat itu pakai TABLESAMPLE.
Ini yang paling sering bikin orang bingung sejam.
SELECT 7 / 2 AS hasil; -- 3, bukan 3.5
Kalau dua-duanya integer, SQL bikin hasilnya juga integer. Desimalnya dibuang, bukan dibulatkan.
Efeknya di laporan nyata:
-- SALAH: hasilnya 0 semua
SELECT cabang, realisasi / target * 100 AS persen FROM transaksi;
-- BENER: paksa jadi desimal
SELECT cabang, realisasi * 100.0 / target AS persen FROM transaksi;
Kenapa yang pertama 0? Karena realisasi / target dihitung duluan, hasilnya 0 (integer), terus dikali 100 tetap 0.
Dua perbaikan: kalikan 100.0 duluan, atau pakai CAST. Detail konversi tipe data ada di CAST dan CONVERT SQL.
Dataset toko_berkah punya 12 cabang dengan target dan realisasi bulanan. Manajemen mau tau cabang mana yang paling jauh dari target, nggak peduli kelebihan atau kekurangan.
SELECT cabang,
ROUND(realisasi * 100.0 / target, 1) AS pencapaian,
ABS(realisasi - target) AS deviasi,
CASE SIGN(realisasi - target)
WHEN 1 THEN 'Lampaui' ELSE 'Meleset'
END AS arah
FROM transaksi
ORDER BY deviasi DESC;
Hasilnya bikin kaget. Cabang Jakarta yang selama ini dipuji karena lampaui target 7,6% ternyata punya deviasi rupiah paling besar dari semua cabang: Rp6,8 juta.
Artinya proses forecasting buat cabang itu yang paling meleset, walau melesetnya ke arah yang menyenangkan.
Tanpa ABS, insight ini nggak bakal keliatan. Cabang yang lampaui target selalu nangkring di atas waktu diurutkan biasa.
| Fungsi | Fungsinya | Contoh hasil |
|---|---|---|
ABS(-5) | Nilai absolut | 5 |
ROUND(4.56, 1) | Bulatin ke terdekat | 4.6 |
CEIL(4.1) | Selalu ke atas | 5 |
FLOOR(4.9) | Selalu ke bawah | 4 |
TRUNC(-4.3) | Potong desimal | -4 |
MOD(7, 3) | Sisa bagi | 1 |
POWER(2, 10) | Pangkat | 1024 |
SQRT(16) | Akar kuadrat | 4 |
SIGN(-8) | Tanda bilangan | -1 |
RANDOM() | Angka acak 0-1 | 0.4271 |
Semuanya jalan di PostgreSQL. Di MySQL, RANDOM namanya RAND dan TRUNC namanya TRUNCATE. Daftar lengkapnya ada di dokumentasi fungsi matematika PostgreSQL.
Kalau dua-duanya bertipe integer, hasilnya juga integer dan desimalnya dibuang. Tulis 7 / 2.0 atau bungkus pakai CAST. Ini penyebab nomor satu persentase di laporan keluar 0 semua.
ROUND membulatkan ke angka terdekat: 4.6 jadi 5, 4.3 jadi 4. CEIL selalu ke atas: 4.1 jadi 5. FLOOR selalu ke bawah: 4.9 jadi 4. Buat hitung jumlah dus atau kendaraan yang dibutuhkan, pakai CEIL. Sisa 1 item tetap butuh 1 dus tambahan. Buat laporan angka biasa, ROUND yang paling pas.
Beda cuma di angka negatif. FLOOR(-4.3) hasilnya -5, TRUNC(-4.3) hasilnya -4. Buat angka positif, dua-duanya sama.
Buat bagi data jadi grup secara merata. MOD(id, 2) ngasih 0 atau 1, pas buat A/B test. Konsisten tiap kali dijalankan.
ORDER BY RANDOM() LIMIT n di PostgreSQL. Lambat di tabel besar karena harus ngurutin semua baris dulu. Buat tabel jutaan baris, pakai TABLESAMPLE.
Tiga yang paling sering nyelametin aku:
Kalau kamu udah nyaman sama fungsi matematika, langkah berikutnya biasanya agregasi. Lanjut ke fungsi agregat SQL.
Mau latihan langsung tanpa install database? Coba modul latihan query di NgulikSQL.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Cara mengisi tanggal kosong di time series SQL pakai generate_series dan LEFT JOIN biar grafik dan laporan gak bolong. Contoh penjualan harian UMKM.
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.