NULL dalam Agregat, JOIN, dan DISTINCT
Pelajari perbedaan perilaku NULL dalam pengelompokan, penggabungan, dan keunikan.
NULL dalam Agregat, JOIN, dan DISTINCT adalah pelajaran SQL Interview Prep gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar SQL Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus SQL Interview Prep mencakup 4 pelajaran total.
NULL di Tiga Tempat yang Mengejutkan
NULL tidak berperilaku sama di semua tempat. Pelajaran terakhir ini membahas tiga konteks yang perilakunya paling sering mengejutkan kandidat: fungsi agregat, JOIN, dan DISTINCT / GROUP BY.
Pola yang berulang adalah bahwa fungsi agregat dan penyaringan memperlakukan NULL sebagai "abaikan saya", sedangkan pengelompokan dan DISTINCT memperlakukan NULL sebagai "nilai yang sama dengan NULL lainnya". Ketidakkonsistenan inilah yang sering digali pewawancara.
Kuasai hal-hal ini dan Anda telah menuntaskan pertanyaan NULL yang paling umum dalam penyaringan SQL.
Fungsi Agregat Mengabaikan NULL
Aturan utamanya: fungsi agregat melewati NULL. SUM, AVG, MIN, MAX, dan COUNT(column) sepenuhnya mengabaikan masukan NULL, bukan memperlakukannya sebagai nol.
Inilah alasan AVG dapat menghasilkan angka yang berbeda dari perkiraan Anda. AVG membagi jumlah nilai yang bukan NULL dengan jumlah nilai yang bukan NULL, bukan dengan jumlah seluruh baris.
-- bonus values: 100, 200, NULL
SELECT
SUM(bonus) AS total, -- 300 (NULL ignored)
AVG(bonus) AS average, -- 150 = 300 / 2, not / 3
COUNT(bonus) AS cnt -- 2 (NULL not counted)
FROM employees;COUNT(*) dibandingkan dengan COUNT(column)
Inilah pertanyaan tentang NULL pada fungsi agregat yang paling sering diajukan. COUNT(*) menghitung baris, termasuk baris yang memiliki NULL. COUNT(column) hanya menghitung baris yang kolomnya bukan NULL.
Jadi, selisih antara keduanya tepat sama dengan jumlah NULL pada kolom tersebut. COUNT(DISTINCT column) melangkah lebih jauh dengan juga mengabaikan NULL sekaligus menghapus duplikat.
SELECT
COUNT(*) AS rows_total, -- all rows
COUNT(bonus) AS non_null_bonus, -- excludes NULLs
COUNT(DISTINCT bonus) AS distinct_bonus, -- excludes NULLs + dups
COUNT(*) - COUNT(bonus) AS null_bonus
FROM employees;AVG dibandingkan dengan SUM/COUNT(*): Jebakan Klasik
Pewawancara bertanya: "Apakah AVG(x) sama dengan SUM(x) / COUNT(*)?" Jawabannya adalah tidak jika terdapat NULL.
AVG(x) sama dengan SUM(x) / COUNT(x), yaitu membagi dengan jumlah nilai yang bukan NULL. Sebaliknya, membagi dengan COUNT(*) memperlakukan NULL seolah-olah bernilai nol, sehingga rata-ratanya menjadi lebih rendah.
Jika Anda memang ingin NULL dihitung sebagai nol, nyatakan hal itu secara eksplisit dengan COALESCE.
-- These differ when bonus has NULLs:
SELECT
AVG(bonus) AS avg_ignoring_nulls,
SUM(bonus) * 1.0 / COUNT(*) AS avg_nulls_as_zero,
AVG(COALESCE(bonus, 0)) AS explicit_nulls_as_zero
FROM employees;Kasus Khusus Agregat dengan Semua Nilai NULL
Apa yang dikembalikan fungsi agregat ketika semua masukan bernilai NULL atau tidak ada baris? Berikut pembedaan penting yang disukai pewawancara:
SUM,AVG,MIN, danMAXuntuk semua baris yang NULL (atau ketika tidak ada baris) mengembalikan NULL.COUNTselalu mengembalikan 0, tidak pernah NULL.
Jadi, jika laporan menampilkan total kosong, kemungkinan penyebabnya adalah SUM yang seluruh masukannya NULL. Bungkus dengan COALESCE untuk menampilkan 0.
-- No matching rows or all bonuses NULL:
SELECT SUM(bonus) FROM employees WHERE 1 = 0; -- NULL
SELECT COUNT(bonus) FROM employees WHERE 1 = 0; -- 0
-- Present a clean zero:
SELECT COALESCE(SUM(bonus), 0) FROM employees;NULL dalam Kondisi JOIN
Dalam klausa ON pada JOIN, NULL = NULL tetap bernilai UNKNOWN, sehingga kunci NULL tidak pernah cocok dalam equi-JOIN. Dua baris yang keduanya memiliki kunci JOIN NULL tidak akan dipasangkan.
Hal ini sering menjebak orang yang melakukan JOIN menggunakan kunci asing opsional. Jika pencocokan NULL dengan NULL memang diinginkan, Anda memerlukan operator yang aman terhadap NULL (IS NOT DISTINCT FROM atau <=>) dari pelajaran sebelumnya.
-- Rows with region IS NULL on both sides do NOT match
SELECT *
FROM a JOIN b ON a.region = b.region;
-- To match NULL-to-NULL (ANSI):
SELECT *
FROM a JOIN b ON a.region IS NOT DISTINCT FROM b.region;NULL yang Dihasilkan oleh JOIN Luar
JOIN luar menghasilkan NULL untuk baris yang tidak memiliki kecocokan. Setelah LEFT JOIN, setiap kolom di sisi kanan bernilai NULL untuk baris di sisi kiri yang tidak menemukan kecocokan.
Inilah dasar pola anti-JOIN: gunakan filter WHERE right_table.key IS NULL untuk menemukan baris yang tidak memiliki kecocokan, seperti pelanggan tanpa pesanan.
Namun, berhati-hatilah: memfilter kolom hasil JOIN luar dalam WHERE dapat secara tidak sengaja mengubahnya kembali menjadi JOIN dalam, yang akan dibahas pada adegan berikutnya.
-- Find customers who have never ordered (anti-join)
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;Jebakan NULL pada WHERE di JOIN Luar
Ini adalah jebakan yang sering muncul. Anda menggunakan LEFT JOIN untuk menggabungkan tabel pesanan, lalu menambahkan WHERE o.status = 'shipped'. Tiba-tiba pelanggan tanpa pesanan menghilang, sehingga JOIN luar Anda secara efektif menjadi JOIN dalam.
Mengapa? Untuk baris yang tidak memiliki kecocokan, o.status bernilai NULL, dan NULL = 'shipped' bernilai UNKNOWN, sehingga WHERE membuang baris tersebut. Untuk mempertahankan baris yang tidak memiliki kecocokan, pindahkan kondisi itu ke dalam klausa ON.
-- Accidental inner join: drops customers with no orders
SELECT c.name, o.status
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'shipped';
-- Correct: keep unmatched customers
SELECT c.name, o.status
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id AND o.status = 'shipped';DISTINCT Menganggap Semua NULL Sama
Inilah ketidakkonsistenan yang mengejutkan semua orang. Agregat melewati NULL, tetapi DISTINCT mempertahankan tepat satu NULL, dengan menganggap semua NULL sebagai duplikat satu sama lain.
Jadi, SELECT DISTINCT bonus pada nilai 100, 100, NULL, NULL mengembalikan tiga baris: 100, NULL, dan selesai. Kedua NULL tersebut digabungkan menjadi satu, meskipun NULL = NULL bernilai UNKNOWN di tempat lain.
-- bonus: 100, 100, NULL, NULL, 200
SELECT DISTINCT bonus FROM employees;
-- Returns: 100, 200, NULL (the two NULLs become one row)GROUP BY Menggabungkan NULL ke Satu Grup
GROUP BY mengikuti aturan yang sama seperti DISTINCT: semua kunci NULL dikumpulkan ke dalam satu grup. Hal ini berlawanan dengan logika perbandingan, yang membuat NULL tidak pernah sama satu sama lain.
Jadi, pengelompokan berdasarkan kolom yang dapat berisi NULL menghasilkan satu baris yang mewakili semua record berkunci NULL. Biasanya, inilah yang Anda inginkan untuk pelaporan. Sebutkan perbedaan ini (pengelompokan dan perbandingan) untuk menunjukkan pemahaman yang mendalam.
-- All employees with NULL department form ONE group
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;
-- A single row where department is NULL totals all of themPoin Pembahasan Wawancara
Ringkasan terpadu yang mengesankan pewawancara:
- Agregat mengabaikan NULL; AVG membagi dengan COUNT(kolom), bukan COUNT(*).
- COUNT(*) menghitung baris; COUNT(col) dan COUNT(DISTINCT col) melewati NULL.
- SUM/AVG/MIN/MAX pada tidak adanya baris menghasilkan NULL; COUNT menghasilkan 0.
- Dalam penggabungan, kunci NULL tidak pernah cocok; memfilter kolom hasil penggabungan luar dalam WHERE secara diam-diam mengubahnya menjadi penggabungan dalam.
- DISTINCT dan GROUP BY menganggap semua NULL sama, berlawanan dengan logika perbandingan.
Kalimat singkatnya: 'NULL diabaikan saat melakukan agregasi dan perbandingan, tetapi dikelompokkan bersama saat menghapus duplikat.'
Uji Cepat
Uji perbedaan antara pengelompokan dan agregasi.
Ringkasan
Anda telah menyelesaikan materi penanganan NULL untuk wawancara:
- Agregat melewati NULL; AVG membagi dengan jumlah nilai yang bukan NULL, dan SUM yang seluruh nilainya NULL menghasilkan NULL sedangkan COUNT menghasilkan 0.
COUNT(*)menyertakan baris NULL;COUNT(col)tidak, dan selisihnya sama dengan jumlah NULL.- Kunci penggabungan yang bernilai NULL tidak pernah cocok; memfilter kolom hasil penggabungan luar dalam WHERE dapat mengubahnya menjadi penggabungan dalam.
- DISTINCT dan GROUP BY menggabungkan semua NULL menjadi satu, kebalikan dari logika perbandingan.
Ingat mantra ini: NULL diabaikan saat melakukan agregasi dan perbandingan, tetapi dikelompokkan bersama saat menghapus duplikat. Satu pemahaman ini menjawab sebagian besar pertanyaan wawancara tentang NULL.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “NULL dalam Agregat, JOIN, dan DISTINCT” gratis?
Ya — teks lengkap “NULL dalam Agregat, JOIN, dan DISTINCT” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus SQL Interview Prep, upgrade ke CoddyKit PRO. Kursus SQL Interview Prep mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “NULL dalam Agregat, JOIN, dan DISTINCT”?
Pelajari perbedaan perilaku NULL dalam pengelompokan, penggabungan, dan keunikan. Kamu berlatih SQL Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai SQL Interview Prep?
Tidak diperlukan pengalaman sebelumnya. SQL Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “NULL dalam Agregat, JOIN, dan DISTINCT” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran SQL Interview Prep ini?
Ya. Setiap pelajaran SQL Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Logika Tiga Nilai dan UNKNOWN
- IS NULL, IS NOT NULL, dan Kesetaraan yang Aman terhadap NULL
- COALESCE, NULLIF, dan ISNULL
- NULL dalam Agregat, JOIN, dan DISTINCT