Logica a tre valori e UNKNOWN
Capire perché NULL = NULL non è vero e come UNKNOWN si propaga nelle condizioni
Logica a tre valori e UNKNOWN è una lezione SQL Interview Prep gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento SQL Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso SQL Interview Prep include 4 lezioni in totale.
Perché NULL mette in difficoltà i candidati
NULL è la principale fonte di risposte errate nei colloqui SQL. La trappola consiste nel trattarlo come un valore normale, mentre in realtà NULL significa «sconosciuto» o «mancante», non zero e non una stringa vuota.
Gli intervistatori lo apprezzano perché la sintassi sembra corretta, ma il risultato è silenziosamente errato. Potrebbero mostrarle un filtro che «dovrebbe» restituire una riga e chiederle perché non restituisce nulla.
In questa lezione costruirà il modello mentale che permette di risolvere qualsiasi domanda su NULL: la logica a tre valori. Una volta interiorizzato che i confronti possono restituire TRUE, FALSE o UNKNOWN, il resto viene naturale.
NULL non è un valore
La frase più importante da dire in un colloquio è: NULL è l'assenza di un valore, non un valore in sé.
Questo significa che non è possibile confrontarlo con = come si confrontano i numeri. Il database non può sapere se due valori sconosciuti sono uguali, quindi non decide se il risultato è TRUE o FALSE.
NULL = 5non è FALSE, ma UNKNOWNNULL = NULLnon è TRUE, ma UNKNOWNNULL <> NULLè anch'esso UNKNOWN
Per questo un filtro di uguaglianza ingenuo su una colonna che ammette NULL elimina silenziosamente le righe.
Logica a due valori e a tre valori
La maggior parte dei linguaggi di programmazione usa la logica a due valori: un'espressione è TRUE oppure FALSE. SQL aggiunge un terzo esito, UNKNOWN, quando in un confronto è coinvolto un NULL.
Quindi qualsiasi predicato in SQL può produrre uno di tre risultati: TRUE, FALSE o UNKNOWN. La clausola WHERE mantiene una riga solo quando il suo predicato è esattamente TRUE. UNKNOWN si comporta come FALSE nei filtri, ma logicamente non è la stessa cosa.
Gli intervistatori verificano che conosca questa distinzione, perché UNKNOWN si comporta diversamente sotto NOT rispetto a FALSE.
Un filtro che elimina silenziosamente le righe
Ecco il classico esempio guidato. Supponga che bonus sia talvolta NULL. Un selezionatore le chiede: «Questa query dovrebbe restituire tutti coloro il cui bonus non è 1000. Perché esclude i dipendenti senza bonus?»
Per una riga in cui bonus è NULL, bonus <> 1000 restituisce UNKNOWN, non TRUE. WHERE conserva solo le righe con TRUE, quindi quei dipendenti scompaiono.
La soluzione consiste nel gestire esplicitamente NULL, come vedremo nella prossima lezione. Per ora, riconosca che le righe mancanti sono una conseguenza della logica, non un bug.
SELECT name, bonus
FROM employees
WHERE bonus <> 1000;
-- Rows where bonus IS NULL are excluded:
-- NULL <> 1000 evaluates to UNKNOWN, not TRUENULL nelle espressioni AND
La logica a tre valori cambia il comportamento di AND. Memorizzi questa regola e potrà rispondere subito a qualsiasi domanda sulle tavole di verità.
- TRUE AND UNKNOWN = UNKNOWN
- FALSE AND UNKNOWN = FALSE
- UNKNOWN AND UNKNOWN = UNKNOWN
L'intuizione è questa: AND ha bisogno di un solo FALSE per essere definitivamente FALSE. Quindi FALSE AND qualsiasi altra cosa resta FALSE. TRUE AND un valore sconosciuto, invece, resta sconosciuto, perché il lato sconosciuto potrebbe assumere uno dei due valori.
-- If status = 'active' is TRUE but bonus = 100 is UNKNOWN:
SELECT *
FROM employees
WHERE status = 'active' AND bonus = 100;
-- Combined result is UNKNOWN, so the row is NOT returnedNULL nelle espressioni OR
OR è lo specchio di AND. Ha bisogno di un solo TRUE per essere definitivamente TRUE, quindi TRUE rende irrilevante il valore sconosciuto.
- TRUE OR UNKNOWN = TRUE
- FALSE OR UNKNOWN = UNKNOWN
- UNKNOWN OR UNKNOWN = UNKNOWN
Una riga può quindi soddisfare una condizione OR anche quando uno dei rami è sconosciuto, purché un altro ramo sia effettivamente TRUE. È una domanda frequente dopo quella su AND.
SELECT *
FROM employees
WHERE department = 'Sales' OR bonus = 100;
-- A Sales employee with NULL bonus:
-- TRUE OR UNKNOWN = TRUE, so the row IS returnedNOT inverte TRUE/FALSE, ma non UNKNOWN
Ecco il caso più sottile, che gli intervistatori tengono spesso per ultimo. NOT trasforma TRUE in FALSE e FALSE in TRUE, ma NOT UNKNOWN resta UNKNOWN.
Per questo non è possibile racchiudere semplicemente una condizione che non dà il risultato atteso in NOT per invertirla. Se bonus = 1000 è UNKNOWN per una riga con NULL, anche NOT (bonus = 1000) è UNKNOWN e la riga viene comunque esclusa.
La negazione non recupera le righe NULL. Solo un test esplicito con IS NULL lo permette.
-- For a row where bonus IS NULL:
-- bonus = 1000 -> UNKNOWN
-- NOT (bonus = 1000) -> UNKNOWN (still excluded)
SELECT * FROM employees WHERE NOT (bonus = 1000);Esempio guidato: la trappola di NOT IN
Questo è uno degli enigmi su NULL più frequenti. NOT IN con un elenco che contiene un NULL non restituisce nessuna riga, sorprendendo i candidati che si aspettano che il NULL venga semplicemente ignorato.
In realtà, x NOT IN (1, 2, NULL) si espande in x <> 1 AND x <> 2 AND x <> NULL. L'ultimo confronto è UNKNOWN e TRUE AND TRUE AND UNKNOWN diventa UNKNOWN, quindi nulla soddisfa la condizione.
L'alternativa sicura è NOT EXISTS, che non presenta questo problema.
-- Returns ZERO rows if the subquery yields any NULL
SELECT name
FROM employees
WHERE manager_id NOT IN (SELECT manager_id FROM managers);
-- Each comparison against NULL becomes UNKNOWN,
-- and the AND-chain collapses to UNKNOWN for every row.Perché UNKNOWN si comporta come FALSE in WHERE
Una domanda frequente è: «Se UNKNOWN non è FALSE, perché la riga viene eliminata proprio come una riga FALSE?»
La risposta precisa è che WHERE, ON e HAVING applicano tutti la regola mantieni solo TRUE. Sia FALSE sia UNKNOWN non superano questo test, quindi ai fini del filtraggio sembrano identici.
La differenza emerge solo con la negazione e con i vincoli CHECK. Un vincolo CHECK considera valida una riga quando la condizione è TRUE oppure UNKNOWN, quindi un NULL può superare un vincolo CHECK che si pensava dovesse bloccarlo.
-- CHECK passes on TRUE or UNKNOWN, so NULL salary is allowed:
-- CONSTRAINT salary_positive CHECK (salary > 0)
-- INSERT ... salary = NULL -> NULL > 0 is UNKNOWN -> allowedEsempio più approfondito: COUNT e il divario della logica booleana
Colleghi tutto a una richiesta realistica da colloquio. «Abbiamo 100 dipendenti. SELECT COUNT(*) WHERE bonus = 100 restituisce 30 e WHERE bonus <> 100 restituisce 50. Dove sono gli altri 20?»
I 20 mancanti hanno un bonus NULL. Né = 100 né <> 100 è TRUE per loro: entrambi sono UNKNOWN, quindi queste righe non rientrano in nessuno dei due filtri.
Dire «i gruppi non arrivano al totale perché NULL non soddisfa nessuno dei due predicati» è esattamente la risposta che gli intervistatori vogliono sentire.
SELECT
COUNT(*) FILTER (WHERE bonus = 100) AS eq_100,
COUNT(*) FILTER (WHERE bonus <> 100) AS ne_100,
COUNT(*) FILTER (WHERE bonus IS NULL) AS null_bonus,
COUNT(*) AS total
FROM employees;Punti chiave per il colloquio
Quando si parla della logica di NULL, esponga questi punti per dimostrare esperienza:
- NULL significa sconosciuto; i confronti con NULL producono UNKNOWN.
- SQL usa la logica a tre valori: TRUE, FALSE, UNKNOWN.
- WHERE, ON e HAVING mantengono solo TRUE.
NOT UNKNOWNresta UNKNOWN, quindi la negazione non recupera le righe NULL.NOT INcon qualsiasi NULL non restituisce righe; preferiscaNOT EXISTS.
Esponga prima il modello, poi descriva la tavola di verità. Questo ordine dimostra che comprende il perché, non solo il trucco.
Verifica rapida
Verifichi la sua comprensione della logica a tre valori.
Riepilogo
Ora dispone del modello mentale fondamentale per NULL:
- NULL è sconosciuto, non un valore; non lo confronti mai con
=o<>. - SQL usa tre valori: i predicati restituiscono TRUE, FALSE o UNKNOWN.
- Le clausole di filtraggio mantengono solo TRUE; le righe UNKNOWN scompaiono proprio come quelle FALSE.
NOTinverte TRUE e FALSE, ma lascia invariato UNKNOWN.- La trappola
NOT IN+ NULL restituisce zero righe; usiNOT EXISTS.
Prossimo argomento: il modo corretto di verificare NULL con IS NULL, IS NOT NULL e gli operatori di uguaglianza NULL-safe.
Domande Frequenti
La lezione «Logica a tre valori e UNKNOWN» è gratuita?
Sì — il testo completo di «Logica a tre valori e UNKNOWN» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso SQL Interview Prep, passa a CoddyKit PRO. Il corso SQL Interview Prep include 4 lezioni in totale.
Cosa imparerò in «Logica a tre valori e UNKNOWN»?
Capire perché NULL = NULL non è vero e come UNKNOWN si propaga nelle condizioni Eserciti SQL Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare SQL Interview Prep?
Non è richiesta alcuna esperienza precedente. SQL Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Logica a tre valori e UNKNOWN»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione SQL Interview Prep?
Sì. Ogni lezione SQL Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Logica a tre valori e UNKNOWN
- IS NULL, IS NOT NULL ed eguaglianza NULL-safe
- COALESCE, NULLIF e ISNULL
- NULL in aggregati, join e DISTINCT