DataLens

Fungsi agregat (COUNT, SUM, AVG)

Ubah banyak baris menjadi satu jawaban: berapa banyak, berapa jumlahnya, rata-ratanya, yang terkecil dan yang terbesar.

Level: Menengah · 8 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Sebagian besar pertanyaan bisnis bukan "tampilkan baris-barisnya", melainkan "beri aku sebuah angka": berapa banyak pesanan yang kita dapat, berapa total pendapatan kita, berapa rata-rata gajinya? Fungsi agregat menjawabnya. Fungsi ini menerima seluruh kolom berisi nilai-nilai dan memadatkannya menjadi satu nilai.

Analogi

Agregat adalah status bar di bagian bawah Excel saat kamu memilih sebuah kolom: Count, Sum, Average. SQL memberimu angka-angka yang sama, tapi untuk jutaan baris dan di dalam query yang bisa kamu simpan dan jalankan ulang.

Lima yang akan kamu pakai setiap hari

FungsiMengembalikan
COUNT(*)jumlah baris
SUM(col)total dari nilai-nilainya
AVG(col)rata-rata (mean) dari nilai-nilainya
MIN(col)nilai terkecil
MAX(col)nilai terbesar
SELECT COUNT(*) AS products,
       MIN(price) AS cheapest,
       MAX(price) AS priciest,
       AVG(price) AS avg_price
FROM products;
 products | cheapest | priciest | avg_price
----------+----------+----------+---------------------
       15 |    38000 |   320000 | 131066.666666666667
(1 row)

Lima belas baris masuk, satu baris keluar. Itulah yang dilakukan agregat.

Rata-ratanya punya banyak desimal. ROUND memperbaikinya, seperti yang kamu lihat di modul ekspresi:

SELECT ROUND(AVG(price)) AS avg_price
FROM products;
 avg_price
-----------
    131067
(1 row)

MIN dan MAX juga bekerja pada teks (alfabetis) dan tanggal (paling awal/paling akhir):

SELECT MIN(order_date) AS first_order,
       MAX(order_date) AS last_order
FROM orders;
 first_order | last_order
-------------+------------
 2024-01-03  | 2024-06-29
(1 row)

Mengagregasi sebuah perhitungan

Pendapatan dari satu baris pesanan adalah quantity * unit_price. Taruh perhitungannya di dalam SUM, maka ia dihitung per baris, lalu dijumlahkan:

SELECT SUM(quantity) AS units_sold,
       SUM(quantity * unit_price) AS revenue
FROM order_items;
 units_sold | revenue
------------+----------
        117 | 17502000
(1 row)

Agregat dengan WHERE

Biasanya kamu tidak ingin menghitung semuanya. "Berapa pesanan yang kita dapat?" kurang berguna dibanding "berapa pesanan yang benar-benar jadi?", karena pesanan yang dibatalkan tidak menghasilkan uang. Kamu bisa menggabungkan agregat dengan WHERE. WHERE berjalan lebih dulu, membuang baris-baris yang tidak cocok, dan agregat hanya melihat sisanya:

SELECT COUNT(*) AS completed_orders
FROM orders
WHERE status = 'completed';
 completed_orders
------------------
               26
(1 row)

Tiga jenis COUNT

"Berapa pelanggan yang kita punya?", "berapa yang sudah memberi kita email?", dan "mereka tersebar di berapa kota?" semuanya terdengar seperti pertanyaan menghitung, dan memang begitu, tapi masing-masing butuh COUNT yang sedikit berbeda. Tertukar di antaranya adalah kesalahan klasik, jadi ini ketiganya berdampingan:

SELECT COUNT(*) AS customers,
       COUNT(email) AS with_email,
       COUNT(DISTINCT city) AS cities
FROM customers;
 customers | with_email | cities
-----------+------------+--------
        12 |         10 |      8
(1 row)
Ide utama

Semua agregat kecuali COUNT(*) mengabaikan NULL. Itu biasanya yang kamu inginkan, tapi sadari: AVG(stock) adalah rata-rata dari 14 nilai stok yang diketahui, bukan dari ke-15 produk.

Apa yang (belum) bisa kamu lakukan

Coba tampilkan nama produk di sebelah harga tertinggi:

SELECT name, MAX(price)
FROM products;
ERROR: column "products.name" must appear in the GROUP BY clause or be used in an aggregate function

Kedengarannya masuk akal, tapi pikirkan dari sisi database: MAX(price) memadatkan 15 baris menjadi 1, sementara name masih punya 15 nilai. Nama mana yang harus ditaruh di satu baris itu? SQL menolak menebak. Error-nya menyebutkan GROUP BY, yang merupakan modul berikutnya: ia memungkinkanmu mengagregasi per kelompok, seperti harga tertinggi per kategori. (Untuk menemukan produk mana yang termahal, kamu sudah tahu cara yang lebih sederhana: ORDER BY price DESC LIMIT 1.)

Input kosong

Saat tidak ada baris yang cocok, COUNT mengembalikan 0, tapi SUM, AVG, MIN, dan MAX mengembalikan NULL, karena tidak ada yang bisa dijumlahkan:

SELECT COUNT(*) AS n, SUM(salary) AS total
FROM employees
WHERE department = 'Legal';
 n | total
---+-------
 0 |  NULL
(1 row)

Ingat ini saat sebuah dashboard menampilkan sel kosong alih-alih 0: memang tidak ada barisnya.

Mengapa ini penting untuk kode bersih

Mengerjakan hitungan di database berarti satu query, satu angka, sama untuk semua orang. Mengunduh setiap baris ke Excel untuk menjumlahkannya itu lambat dan mengundang kesalahan copy-paste. Beri nama setiap agregat (AS revenue, AS completed_orders), dan pilih COUNT yang tepat dengan sengaja, supaya pembaca tahu persis apa yang sedang dihitung.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: GROUP BY dan HAVING →