Modulelessen (2/4)
Omgaan met NULL's: IS NULL en COALESCE
In de dataset employees is Andrea Costa bijzonder: dat heeft hij gedaan
BESCHERMD_INLINE_1. Je hebt al tegen NULL (met
LEFT JOIN), maar de tijd is gekomen om het serieus te nemen: NULLs in SQL
zich anders gedragen dan welke andere waarde dan ook, en het negeren ervan is een van de
belangrijkste oorzaken van bugs in productiecode.
NULL is niet nul, geen lege tekenreeks
NULL betekent onbekende / ontbrekende waarde. Het is niet 0, niet '', niet
BESCHERMD_INLINE_8. Het is "Ik weet het niet". Hieruit volgt een verrassende eigenschap:
NULL is nergens gelijk aan, zelfs zichzelf niet.
-- All these expressions return NULL (not true!):
SELECT NULL = NULL; -- NULL
SELECT NULL = 0; -- NULL
SELECT NULL <> 'qualcosa'; -- NULLConcreet gevolg: WHERE column = NULL werkt nooit. Je moet gebruiken
de speciale operators 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 – de NULL-terugval
Vaak wil je iets weergeven in plaats van NULL als de gegevens aanwezig zijn
ontbreekt: de string '(none)', nul, een standaarddatum. De functie die
doet precies dit is COALESCE(a, b, c, ...): het retourneert de eerste
niet-NULL-argument in de lijst.
-- Show the department_id, or 0 if missing:
SELECT first_name, last_name, COALESCE(department_id, 0) AS dept
FROM employees;Gecombineerd met een LEFT JOIN wordt het ongelooflijk krachtig voor rapporten:
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;Resultaat: alle medewerkers kwamen terug, met de afdelingsnaam of expliciet label voor degenen die er geen hebben.
NULL en aggregaten
Verzamelfuncties negeer NULLs (behalve COUNT(*)):
COUNT(department_id)telt alleen de rijen met een waarde;AVG(salary)gemiddelden negerenNULLs — het behandelt ze niet als 0;SUM(...)telt alleen de niet-NULL-waarden op.
Dit is bijna altijd wat je wilt. Maar het is goed om te weten: als dat zo is
op zoek naar "het totale aantal werknemers" gebruik COUNT(*), niet
COUNT(department_id).
Probeer het
Toon voor elke medewerker de voornaam (voornaam), achternaam (achternaam) en een kolom 'dipartimento_id' die gelijk is aan hun afdelingsnaam of -1 als deze niet is toegewezen. Drie kolommen, één rij per medewerker.
Toon hint
Gebruik COALESCE(afdeling_id, -1) om NULL's te vervangen door -1.
Oplossing beschikbaar na 3 pogingen
Oefening beoordelen
Retourneer de voornaam (voornaam), achternaam (achternaam) en afdelingsnaam (departments.name) van ALLE werknemers, met '(nessuno)' als de afdeling ontbreekt. Gebruik LINKS JOIN + COALESCE.
Toon hint
COALESCE(d.name, '(nessuno)') verwerkt de NULL die is geïntroduceerd door de LEFT JOIN.
Oplossing beschikbaar na 3 pogingen