Pelajaran modul (2/4)
Menangani NULL: IS NULL dan COALESCE
Dalam kumpulan data employees, Andrea Costa istimewa: dia punya
department_id = NULL. Anda telah menyentuh NULL (dengan
LEFT JOIN), tetapi sudah waktunya untuk menganggapnya serius: NULLs dalam SQL
berperilaku berbeda dari nilai lainnya, dan mengabaikannya adalah salah satunya
penyebab utama bug dalam kode produksi.
NULL bukan nol, bukan string kosong
NULL berarti nilai tidak diketahui/hilang. Ini bukan 0, bukan '', bukan
false. Itu adalah "Saya tidak tahu". Dari sini berikut properti yang mengejutkan:
NULL tidak setara dengan apapun, bahkan dirinya sendiri.
-- All these expressions return NULL (not true!):
SELECT NULL = NULL; -- NULL
SELECT NULL = 0; -- NULL
SELECT NULL <> 'qualcosa'; -- NULLKonsekuensi nyata: WHERE column = NULL tidak pernah berhasil. Anda harus menggunakan
operator khusus IS NULL / IS NOT NULL:
-- Employees without a department:
SELECT first_name, last_name
FROM employees
WHERE department_id IS NULL;
-- Employees WITH a department:
SELECT first_name, last_name
FROM employees
WHERE department_id IS NOT NULL;COALESCE - cadangan NULL
Seringkali Anda ingin menampilkan sesuatu alih-alih NULL saat datanya
hilang: string '(none)', nol, tanggal default. Fungsi itu
melakukan hal ini adalah COALESCE(a, b, c, ...): ia mengembalikan pertama
argumen non-NULL dalam daftar.
-- Show the department_id, or 0 if missing:
SELECT first_name, last_name, COALESCE(department_id, 0) AS dept
FROM employees;Dikombinasikan dengan LEFT JOIN, ini menjadi sangat berguna untuk laporan:
SELECT e.first_name,
e.last_name,
COALESCE(d.name, '(nessun dipartimento)') AS dipartimento
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id;Hasil: semua karyawan kembali, dengan nama departemen atau yang jelas label bagi mereka yang tidak memilikinya.
NULL dan agregat
Fungsi agregat abaikan NULLs (kecuali COUNT(*)):
COUNT(department_id)hanya menghitung baris dengan nilai;AVG(salary)rata-rata mengabaikanNULLs — tidak memperlakukannya sebagai 0;SUM(...)hanya menjumlahkan nilai bukan NULL.
Ini hampir selalu yang Anda inginkan. Namun ada baiknya untuk mengetahui: jika memang demikian
mencari _"jumlah total karyawan" menggunakan COUNT(*), bukan
COUNT(department_id).
Cobalah
Untuk setiap karyawan, tampilkan nama depan (first_name), nama belakang (last_name) dan kolom 'dipartimento_id' yang sama dengan department_id atau -1 jika tidak ditetapkan. Tiga kolom, satu baris per karyawan.
Tunjukkan petunjuk
Gunakan COALESCE(department_id, -1) untuk mengganti NULL dengan -1.
Solusi tersedia setelah 3 upaya
Tinjau latihan
Mengembalikan nama depan (first_name), nama belakang (last_name) dan nama departemen (departments.name) dari SEMUA karyawan, menampilkan '(nessuno)' ketika departemen tersebut hilang. Gunakan KIRI GABUNG + COALESCE.
Tunjukkan petunjuk
COALESCE(d.name, '(nessuno)') menangani NULL yang diperkenalkan oleh LEFT JOIN.
Solusi tersedia setelah 3 upaya