Perbedaan Count Sum Avg Sql

Perbedaan COUNT, SUM, dan AVG di SQL, Fungsi Agregat
fungsi agregat itu fungsi di sql yang ngerjain perhitungan pada sekumpulan baris dan ngembaliin satu nilai ringkasan. yang paling sering dipakai ada tiga: COUNT, SUM, dan AVG.
ketiga fungsi ini paling sering saya pakai waktu bikin laporan: jumlah pengguna, total penjualan, rata-rata nilai. yang perlu diingat sejak awal, fungsi agregat itu menggabungkan banyak baris jadi satu nilai, jadi kalau digabung sama kolom biasa, wajib pakai GROUP BY. kesalahan ini adalah error sql paling umum yang pernah saya lihat, termasuk di kode saya sendiri 🙂
1. COUNT: Menghitung Jumlah Baris
COUNT() ngembaliin jumlah baris dalam suatu query. bentuknya bermacam-macam tergantung yang mau dihitung:
-- Hitung semua baris
SELECT COUNT(*) FROM mahasiswa;
-- Hitung baris dengan nilai tidak NULL
SELECT COUNT(nim) FROM mahasiswa;
-- Hitung baris unik
SELECT COUNT(DISTINCT jurusan) FROM mahasiswa;
-- Dengan kondisi
SELECT COUNT(*) FROM mahasiswa WHERE ipk >= 3.0;
empat bentuk di atas hasilnya beda-beda artinya:
COUNT(*), menghitung semua baris hasil query, mau kolomnya berisi NULL atau nggak, tetap dihitungCOUNT(nim), menghitung baris yang kolomnim-nya tidak NULL. kalau ada baris dengannimNULL, baris itu dilewatiCOUNT(DISTINCT jurusan), menghitung nilai unik di kolomjurusan. kalau ada 100 mahasiswa tapi cuma 5 jurusan, hasilnya 5COUNT(*)denganWHERE, menghitung baris yang memenuhi kondisi aja
COUNT(*) vs COUNT(kolom)
bagian ini paling sering bikin orang salah paham, jadi mari kita lihat contoh nyatanya:
-- COUNT(*) — semua baris, termasuk NULL
SELECT COUNT(*) FROM mahasiswa; -- 100
-- COUNT(kolom) — hanya baris dengan nilai tidak NULL
SELECT COUNT(alamat) FROM mahasiswa; -- 85 (15 NULL)
di contoh ini ada 100 baris mahasiswa, tapi 15 di antaranya kolom alamat-nya kosong (NULL). COUNT(*) tetap balik 100, sedangkan COUNT(alamat) cuma balik 85.
kenapa ini penting? karena banyak laporan sederhana yang pakai hitungan “jumlah data lengkap”. kalau misalnya form pendaftaran tidak mewajibkan alamat, maka COUNT(alamat) akan selalu lebih kecil dari COUNT(*), dan itu bukan bug, itu memang cara kerja NULL.
perbedaan
COUNT(*)danCOUNT(kolom)inilah yang sering menghasilkan laporan “selisih beberapa angka” tanpa terlihat salah, saya pernah ngalamin sendiri. kalau jumlahnya tidak sesuai yang kalian harapkan, cek dulu apakah ada nilai NULL di kolom yang dihitung, itu penyebab paling umum.
sekalian bongkar satu mitos yang sering beredar di forum: katanya COUNT(1) lebih cepet dari COUNT(*), atau harus pakai COUNT(id) biar cepat karena primary key. di mysql modern ketiganya dioptimasi jadi sama aja, jadi silakan pakai COUNT(*) saja karena paling gampang dibaca. yang beneran bikin hasil beda ya cuma COUNT(kolom) tadi, soal NULL. oh iya, kalau fokus kalian memang cuma di COUNT, saya punya artikel khusus soal cara menghitung jumlah record pada MySQL yang bahas lebih dalem, termasuk cara nampilin hasilnya di PHP.
2. SUM: Menjumlahkan Nilai
SUM() menjumlahkan nilai numerik dalam satu kolom. yang dijumlahkan harus angka, kalau kolomnya string atau tanggal, hasilnya bakal error atau aneh:
-- Total penjualan
SELECT SUM(total) FROM transaksi;
-- Total penjualan per bulan
SELECT MONTH(tanggal) as bulan, SUM(total) as total
FROM transaksi
GROUP BY MONTH(tanggal);
-- Dengan kondisi
SELECT SUM(total) FROM transaksi
WHERE status = 'lunas';
contoh kedua itu pola yang paling sering dipakai di laporan keuangan, total penjualan per bulan. MONTH(tanggal) memecah tanggal jadi angka bulan, 1 sampai 12, lalu SUM(total) menjumlahkan penjualan di tiap bulan.
satu hal yang jarang disadari: SUM() juga mengabaikan nilai NULL. kalau kolom yang dijumlahkan ada NULL di tengah-tengah, NULL itu dilewati, sisanya tetap dijumlahkan. bedanya dengan COUNT, kalau SEMUA barisnya NULL, SUM() baliknya NULL, bukan 0:
-- Kalau semua nilai total NULL, hasilnya NULL, bukan 0
SELECT SUM(total) FROM transaksi WHERE status = 'batal';
-- Supaya aman, bungkus COALESCE biar balik 0
SELECT COALESCE(SUM(total), 0) FROM transaksi WHERE status = 'batal';
di laporan, NULL itu berbahaya karena ditampilkan sebagai kosong atau error tersendiri di aplikasi. bungkus COALESCE(SUM(...), 0) itu kebiasaan yang saya sarankan buat semua laporan, biar angkanya selalu konsisten.
Trik: hitung beberapa kondisi sekaligus pakai SUM
ini trik favorit saya yang jarang diajarkan di tutorial dasar: SUM() bisa dipakai buat menghitung baris yang memenuhi kondisi tertentu, tanpa harus menjalankan query terpisah. idenya, SUM menjumlahkan hasil ekspresi yang bernilai 1 kalau kondisinya terpenuhi dan 0 kalau tidak:
SELECT
COUNT(*) as total_transaksi,
SUM(status = 'lunas') as transaksi_lunas,
SUM(status = 'pending') as transaksi_pending,
SUM(total >= 1000000) as transaksi_besar
FROM transaksi;
satu query, empat angka. status = 'lunas' di mysql itu baliknya 1 atau 0, jadi langsung bisa dijumlahkan. di database lain seperti PostgreSQL yang nggak otomatis konversi boolean ke angka, bentuk panjangnya pakai CASE WHEN:
SUM(CASE WHEN status = 'lunas' THEN 1 ELSE 0 END)
dulu saya suka nulis tiga query terpisah buat dapetin tiga angka kayak gini, terus sadar bisa digabung pas lihat kode orang lain. hemat round-trip ke database, apalagi kalau tabelnya besar.
3. AVG: Rata-rata
AVG() ngitung nilai rata-rata dari satu kolom numerik. secara teknis, AVG(kolom) itu sama dengan SUM(kolom) / COUNT(kolom), dengan catatan NULL diabaikan di keduanya:
-- Rata-rata IPK
SELECT AVG(ipk) FROM mahasiswa;
-- Rata-rata per jurusan
SELECT jurusan, AVG(ipk) as rata_ipk
FROM mahasiswa
GROUP BY jurusan;
-- Rata-rata dengan pembulatan
SELECT ROUND(AVG(total), 2) FROM transaksi;
contoh kedua menghasilkan satu baris per jurusan lengkap dengan rata-rata IPK masing-masing. ini pola dasar semua laporan statistik per kelompok.
AVG jarang balik angka yang bulat enak, makanya ROUND(..., 2) itu teman setia AVG. tanpa ROUND, hasil rata-rata bisa panjang banget, kayak 3.45678901, dan itu bikin laporan jelek dibaca.
satu catatan penting soal AVG dan NULL: kalau kolomnya ada NULL, AVG ngitung dari baris yang tidak NULL aja. contohnya lima mahasiswa, empat nilai 80 dan satu NULL, AVG(nilai) balik 80, bukan 64. kalau kalian mau NULL dihitung sebagai 0, harus diubah dulu pakai COALESCE:
-- NULL dihitung sebagai 0
SELECT AVG(COALESCE(nilai, 0)) FROM mahasiswa;
satu lagi soal AVG yang perlu diwaspadai: rata-rata itu gampang “diracuni” oleh nilai ekstrem. contohnya di studi kasus nanti, AVG(harga) jadi 165 ribu padahal kebanyakan barangnya cuma 250-500 ribu, karena ada Laptop 15 juta yang menarik angkanya ke atas. kalau kalian nemuin rata-rata yang rasanya nggak masuk akal, cek dulu apakah ada outlier kayak gini, kadang median lebih jujur buat menggambarkan kondisi data.
4. Studi Kasus Lengkap
biar makin kebayang, ini data penjualan sederhana yang menggabungkan ketiga fungsi sekaligus:
-- Data penjualan
CREATE TABLE penjualan (
id INT AUTO_INCREMENT PRIMARY KEY,
produk VARCHAR(50),
jumlah INT,
harga DECIMAL(10,2),
tanggal DATE
);
INSERT INTO penjualan VALUES
(NULL, 'Laptop', 2, 15000000, '2026-08-01'),
(NULL, 'Mouse', 5, 250000, '2026-08-01'),
(NULL, 'Laptop', 1, 15000000, '2026-08-02'),
(NULL, 'Keyboard', 3, 500000, '2026-08-02'),
(NULL, 'Mouse', 2, 250000, '2026-08-03');
-- Analisis
SELECT
COUNT(*) as total_transaksi,
COUNT(DISTINCT produk) as produk_terjual,
SUM(jumlah) as total_unit,
SUM(jumlah * harga) as total_pendapatan,
AVG(harga) as rata_rata_harga,
ROUND(AVG(jumlah * harga), 2) as rata_transaksi
FROM penjualan;
kalau query di atas dijalankan, hasilnya kurang lebih begini:
total_transaksi | produk_terjual | total_unit | total_pendapatan | rata_rata_harga | rata_transaksi
5 | 3 | 13 | 32500000.00 | 165000.00 | 6500000.00
cara baca hasilnya:
COUNT(*)= 5, ada lima baris transaksiCOUNT(DISTINCT produk)= 3, produk yang terjual cuma Laptop, Mouse, dan KeyboardSUM(jumlah)= 13, total unit semua barang yang laku (2+5+1+3+2)SUM(jumlah * harga)= 32500000, total pendapatan, di sini fungsi SUM nerima ekspresi, bukan cuma nama kolomAVG(harga)= 165000.00, ini rata-rata harga per unit; tapi hati-hati, ini agak menyesatkan karena Laptop 15 juta bikin angkanya tinggi padahal jarang terjualROUND(AVG(jumlah * harga), 2)= 6500000.00, rata-rata nilai satu transaksi
perhatikan SUM(jumlah * harga), fungsi agregat itu bisa nerima ekspresi, jadi kalian nggak terbatas cuma menjumlahkan satu kolom. pola ini dipakai terus di laporan penjualan nyata.
studi kasus satu baris kayak di atas bagus buat dashboard, tapi laporan nyata sering butuh perbandingan antar item. misalnya produk mana yang paling banyak terjual:
SELECT produk, SUM(jumlah) as total_terjual
FROM penjualan
GROUP BY produk
ORDER BY total_terjual DESC;
hasilnya:
produk | total_terjual
Mouse | 7
Laptop | 3
Keyboard | 3
pola SELECT ... GROUP BY ... ORDER BY ... DESC ini yang nempel di kepala saya sebagai “pola best seller”, hampir semua laporan ranking dibangun dari sini. mau ranking produk terlaris, penulis paling produktif, atau kelas dengan nilai rata-rata tertinggi, bentuknya sama persis.
5. Perbandingan Singkat
| Fungsi | Mengembalikan | Tipe Data | Bisa dengan DISTINCT |
|---|---|---|---|
| COUNT(*) | Jumlah baris | Integer | ✅ |
| COUNT(kolom) | Jumlah nilai tidak NULL | Integer | ✅ |
| SUM() | Total penjumlahan | Numerik | ✅ |
| AVG() | Rata-rata | Numerik | ✅ |
tabel di atas bisa diringkas jadi tiga pertanyaan yang kalian tanyakan ke data:
- mau tau berapa banyak? pakai COUNT
- mau tau total semua? pakai SUM
- mau tau rata-rata? pakai AVG
selain tiga ini masih ada MIN dan MAX buat nilai terkecil dan terbesar, tapi COUNT, SUM, dan AVG itu yang paling sering kepake sehari-hari.
6. Error Umum dan Cara Mengatasinya
error yang paling sering saya lihat, termasuk di kode saya sendiri dulu, ada dua. yang pertama, kolom non-agregat dicampur fungsi agregat tanpa GROUP BY:
-- ❌ Salah — kolom non-agregat tanpa GROUP BY
SELECT nama, COUNT(*) FROM mahasiswa;
-- ✅ Benar
SELECT jurusan, COUNT(*) FROM mahasiswa GROUP BY jurusan;
kenapa yang pertama error? karena sql bingung: COUNT(*) mau merangkum semua baris jadi satu nilai, tapi nama itu unik per baris. dua hal yang bertentangan. solusinya, kelompokkan dulu barisnya pakai GROUP BY, baru hitung per kelompok.
yang kedua, WHERE dipakai buat filter hasil agregat:
-- ❌ WHERE tidak bisa untuk agregat
SELECT jurusan, AVG(ipk) FROM mahasiswa
WHERE AVG(ipk) > 3.0; -- Error!
-- ✅ Gunakan HAVING
SELECT jurusan, AVG(ipk) as rata_ipk FROM mahasiswa
GROUP BY jurusan
HAVING rata_ipk > 3.0;
ini masalah urutan kerja sql: WHERE jalan duluan, barisnya difilter sebelum dihitung rata-ratanya. padahal AVG(ipk) itu hasil setelah perhitungan. makanya filter atas hasil agregat harus pakai HAVING yang memang jalan setelah pengelompokan dan perhitungan.
WHERE dan HAVING itu juga bisa dipakai bareng dalam satu query, dan ini pola yang sering banget saya pakai di laporan nyata:
SELECT produk, SUM(jumlah) as total_terjual
FROM penjualan
WHERE tanggal >= '2026-08-01'
GROUP BY produk
HAVING SUM(jumlah) > 2
ORDER BY total_terjual DESC;
di sini WHERE menyaring transaksinya dulu (cuma agustus 2026), baru dikelompokkan per produk, terus HAVING buang produk yang totalnya cuma 2 unit ke bawah. dua-duanya ngerjain tugas beda di tahap yang beda.
catatan kecil: HAVING rata_ipk > 3.0 pakai alias juga bisa di mysql, tapi lebih aman tulis ulang fungsinya langsung (HAVING AVG(ipk) > 3.0) karena nggak semua database nerima alias di HAVING.
cara gampang ngingetnya: WHERE buat filter data mentah, HAVING buat filter hasil hitung. pernah kena error Invalid use of group function sendiri? kemungkinan besar kasusnya salah satu dari dua di atas, coba cek query kalian.
Kesimpulan
rangkuman singkatnya:
- COUNT, jawab pertanyaan “berapa baris?”, paling sering
COUNT(*) - SUM, jawab “total berapa?”, misal
SUM(harga * jumlah) - AVG, jawab “rata-ratanya berapa?”, misal
AVG(ipk) - kolom biasa yang digabung fungsi agregat wajib di-GROUP BY, kalau nggak error
- filter hasil agregat pakai HAVING, bukan WHERE
- null itu diabaikan COUNT(kolom), SUM, dan AVG, kalau perlu dihitung bungkus
COALESCE SUM(kondisi)atauSUM(CASE WHEN ...)bisa dipakai buat ngitung beberapa kondisi sekaligus dalam satu query- rata-rata gampang terdistorsi nilai ekstrem, cek dulu outliernya sebelum percaya angka AVG
artikel terkait:
Pertanyaan yang Sering Diajukan
Apa itu fungsi agregat di SQL?
fungsi agregat adalah fungsi yang melakukan perhitungan pada sekumpulan baris dan mengembalikan satu nilai ringkasan, contohnya COUNT, SUM, dan AVG.
Apa bedanya COUNT(*) dan COUNT(kolom) di SQL?
COUNT(*) menghitung semua baris termasuk yang nilainya NULL, sedangkan COUNT(kolom) cuma menghitung baris yang kolomnya tidak NULL.
Kapan harus menggunakan GROUP BY di SQL?
GROUP BY wajib dipakai kalau kolom biasa digabungkan dengan fungsi agregat, misalnya SELECT jurusan, COUNT(*) ... GROUP BY jurusan. tanpa itu, query error.
Kenapa WHERE tidak bisa dipakai untuk filter hasil agregat?
karena WHERE memfilter baris sebelum diagregasi, sedangkan hasil agregat baru ada setelahnya. filter hasil agregat harus pakai HAVING.

