Direct naar de hoofdinhoud
Module 4 · Les 2 van 414/57 in de cursus~10 min
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.

SQL
-- All these expressions return NULL (not true!):
SELECT NULL = NULL;       -- NULL
SELECT NULL = 0;          -- NULL
SELECT NULL <> 'qualcosa'; -- NULL

Concreet gevolg: WHERE column = NULL werkt nooit. Je moet gebruiken de speciale operators IS NULL / IS NOT NULL:

SQL
-- 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.

SQL
-- 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:

SQL
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 negeren NULLs — 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

Oefening#sql.m4.l2.e1
Pogingen: 0Laden…

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.

Editor laden…
Toon hint

Gebruik COALESCE(afdeling_id, -1) om NULL's te vervangen door -1.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#sql.m4.l2.e2
Pogingen: 0Laden…

Retourneer de voornaam (voornaam), achternaam (achternaam) en afdelingsnaam (departments.name) van ALLE werknemers, met '(nessuno)' als de afdeling ontbreekt. Gebruik LINKS JOIN + COALESCE.

Editor laden…
Toon hint

COALESCE(d.name, '(nessuno)') verwerkt de NULL die is geïntroduceerd door de LEFT JOIN.

Oplossing beschikbaar na 3 pogingen