Soal 1Ketika kamu menulis salah satu fungsi agregat COUNT / SUM / AVG / MIN / MAX saja di sebuah SELECT lalu menjalankannya, pada dasarnya hasilnya punya berapa baris?
Fungsi Agregat — COUNT / SUM / AVG / MIN / MAX
Pelajari fungsi agregat SQL COUNT / SUM / AVG / MIN / MAX secara praktik — dari agregasi seluruh tabel hingga menggabungkannya dengan WHERE — memakai data nilai CSV, semuanya langsung di browser kamu.
Data yang akan kita gunakan — tabel score
Pada artikel ini kita bekerja dengan fungsi agregat (fungsi yang melipat banyak baris menjadi satu nilai). Ada berapa baris, berapa totalnya, rata-ratanya, minimum, maksimum — semua ini memampatkan banyak baris menjadi satu angka. Lima yang dasar adalah COUNT / SUM / AVG / MIN / MAX, dan hampir semua angka ringkasan dalam sebuah laporan bisa dibangun hanya dengan ini.
Kumpulan datanya adalah tabel score (30 baris = 10 orang × 3 mata pelajaran Math / English / Science). Dengan menyasar poin pada kolom score, kamu akan mengerjakan agregasi seluruh tabel terlebih dahulu, lalu agregasi setelah mempersempit baris dengan WHERE. Agregasi per grup (seperti rata-rata per mata pelajaran) dibahas pada artikel berikutnya, jadi di sini kita fokus pada melipat seluruh tabel — atau seluruh rentang yang dipersempit oleh WHERE — menjadi satu nilai.
Fungsi agregat: "banyak baris → satu nilai"
Fungsi agregat ditempatkan pada posisi kolom dalam sebuah SELECT.
Yang perlu diwaspadai di sini adalah jangan mencampur kolom biasa dan fungsi agregat dalam `SELECT` yang sama. Kolom biasa seperti name memiliki nilai berbeda per baris, sedangkan fungsi agregat seperti COUNT(*) melipat seluruh tabel (atau seluruh himpunan yang dipersempit oleh `WHERE`) menjadi satu nilai. Kalau kamu menulis keduanya, seperti pada SELECT name, COUNT(*) FROM score;, sisi agregat adalah satu nilai untuk seluruh himpunan sementara name tidak punya jawaban pasti untuk "nilai dari baris yang mana yang harus ditampilkan?". Pada kebanyakan basis data ini adalah sebuah error.
score sebagai masukan, COUNT mengembalikan jumlah baris, SUM totalnya, AVG rata-ratanya, dan MIN / MAX minimum dan maksimum — masing-masing sebagai satu nilai.-- Mengambil jumlah, jumlah jenis berbeda, total, dan rata-rata sekaligus
SELECT
COUNT(*) AS row_count,
COUNT(DISTINCT name) AS name_kinds,
SUM(score) AS total,
AVG(score) AS avg_raw
FROM score
WHERE subject = 'English';
Perbedaan antara COUNT(*) dan COUNT(kolom)
COUNT(*) menghitung jumlah baris itu sendiri. COUNT(kolom) hanya menghitung baris yang kolomnya tidak NULL. Tabel score tidak punya NULL, jadi keduanya menghasilkan 30 yang sama, tetapi untuk kolom yang mengandung NULL kamu akan melihat perbedaan di sini (kita akan memastikan ini nanti memakai tabel yang mengandung NULL). Selain itu, menulis COUNT(DISTINCT kolom) menghitung jumlah jenis berbeda dengan duplikat dihilangkan (pakai pada subject maka kamu mendapat 3, yaitu jumlah mata pelajaran yang berbeda).
Tips — fungsi agregat dan NULL
SUM / AVG / MIN / MAX tidak memasukkan baris NULL ke dalam perhitungan (mengabaikannya). Khususnya, AVG dihitung sebagai jumlah nilai yang bukan NULL ÷ banyaknya nilai yang bukan NULL. Jadi untuk kolom yang mengandung NULL, SUM(kolom) / COUNT(*) (penyebut = semua baris) dan AVG(kolom) (penyebut = banyaknya yang bukan NULL) menghasilkan nilai berbeda. Saat kamu ingin merata-ratakan dengan memperlakukan NULL sebagai 0, tuliskan secara eksplisit dengan sesuatu seperti AVG(COALESCE(kolom, 0)).
Mempersempit sasaran dengan WHERE sebelum mengagregasi
Menambahkan WHERE membuat hanya baris yang cocok dengan kondisi menjadi masukan bagi fungsi agregat. Urutan eksekusinya adalah "FROM membaca semua baris → WHERE mempersempit baris → baris yang tersisa dilipat oleh fungsi agregat". Dengan kata lain, fungsi agregat hanya melihat baris yang lolos WHERE, dan penjumlahan atau rata-rata dihitung setelah penyaringan. Tambahkan WHERE subject = 'Math' maka hanya 10 baris Math yang menjadi sasaran, jadi rata-ratanya menjadi rata-rata Math saja.
FROM membaca 30 baris, WHERE subject = 'Math' mempersempit menjadi 10 baris, dan AVG(score) melipat 10 baris itu saja. Agregasi terjadi setelah penyaringan.-- Jumlah / rata-rata / nilai tertinggi untuk 10 baris Science saja
SELECT
COUNT(*) AS row_count,
ROUND(AVG(score), 1) AS avg_science,
MAX(score) AS top_science
FROM score
WHERE subject = 'Science';
COUNT(kolom) dan NULL, serta pembulatan AVG
Tabel score sejauh ini tidak punya NULL. Mari kita pastikan bagaimana agregasi berubah tergantung ada atau tidaknya NULL, memakai tabel customer yang punya kekosongan (8 orang, dengan NULL pada age / email / country). COUNT(*) adalah jumlah baris, jadi tetap 8, tetapi COUNT(email) hanya menghitung baris yang emailnya terisi, jadi hasilnya 4. Menjalankan COUNT(kolom) pada kolom yang mengandung NULL menghasilkan angka yang lebih kecil daripada COUNT(*) seperti ini.
Selain itu, karena AVG adalah pembagian, ia menghasilkan desimal seperti 31.5. Dalam sebuah laporan akan lebih mudah ditangani kalau kamu membulatkan dengan ROUND(ekspresi, digit), seperti pada ROUND(AVG(age), 2).
customer (8 orang) yang punya NULL, COUNT(*) tetap 8 sedangkan COUNT(email) hanya menghitung 4 baris yang emailnya terisi. Untuk kolom yang mengandung NULL, COUNT(kolom) menghasilkan angka yang lebih kecil daripada COUNT(*).-- Bagaimana COUNT dan AVG berubah dengan adanya NULL
SELECT
COUNT(*) AS rows_all,
COUNT(country) AS with_country,
ROUND(AVG(age), 2) AS avg_age
FROM customer;
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Manakah penjelasan yang benar tentang perbedaan antara COUNT(*) dan COUNT(kolom)?
Soal 3Ketika kamu menambahkan WHERE subject = 'Math' lalu menjalankan AVG(score), pada rentang mana rata-ratanya dihitung?