perché null non è uguale a null false

Stavo leggendo questo articolo: Ottieni null == null in SQL

E il consenso è che quando si tenta di testare l’uguaglianza tra due colonne (nullable) sql, l’approccio corretto è:

where ((A=B) OR (A IS NULL AND B IS NULL)) 

Quando A e B sono NULL, (A = B) restituisce ancora FALSE, poiché NULL non è uguale a NULL. Questo è il motivo per cui è richiesto il controllo extra.

Che dire quando si verificano le disuguaglianze? In seguito alla discussione di cui sopra, mi ha fatto pensare che per testare la disuguaglianza avrei bisogno di fare qualcosa come:

 WHERE ((A  B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)) 

Tuttavia, ho notato che non è necessario (almeno non su Informix 11.5), e posso solo fare:

 where (AB) 

Se A e B sono NULL, restituisce FALSE. Se NULL non è uguale a NULL, non dovrebbe restituire VERO?

MODIFICARE
Queste sono tutte buone risposte, ma penso che la mia domanda fosse un po ‘vaga. Consentitemi di riformulare:

Dato che A o B possono essere NULL, è sufficiente controllare la loro disuguaglianza con

 where (AB) 

O devo controllarlo esplicitamente in questo modo:

 WHERE ((A  B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)) 

FARE RIFERIMENTO a questo thread per la risposta a questa domanda.

le espressioni relazionali che coinvolgono NULL restituiscono di nuovo NULL

modificare

qui, <> sta per operatore binario arbitrario, NULL è il segnaposto SQL e il value è qualsiasi valore ( NULL non è un valore):

  • NULL <> value -> NULL
  • NULL <> NULL -> NULL

la logica è: NULL significa “nessun valore” o “valore sconosciuto”, e quindi qualsiasi confronto con qualsiasi valore effettivo non ha senso.

X = 42 vero, falso o sconosciuto, dato che non sai quale valore (se esiste ) X detiene? SQL dice che è sconosciuto. è X = Y vero, falso o sconosciuto, dato che entrambi sono sconosciuti? SQL dice che il risultato è sconosciuto . e lo dice per qualsiasi operazione relazionale binaria, che è solo logica (anche se i NULL nel modello non sono in primo luogo).

SQL fornisce anche due operatori unfix postati, IS NULL e IS NOT NULL , che restituiscono TRUE o FALSE in base al loro operando.

  • NULL IS NULL -> TRUE
  • NULL IS NOT NULL -> FALSE

Perché quel comportamento segue la logica ternaria stabilita in cui NULL è considerato un valore sconosciuto.

Se pensi a NULL come sconosciuto, diventa molto più intuitivo:

È unknown a uguale a unknown b ? Non c’è modo di saperlo, quindi: unknown .

Tutti i confronti che coinvolgono null sono indefiniti e valutano false. Questa idea, che è ciò che impedisce a null essere valutato come equivalente a null , impedisce anche che null venga valutato come NOT equivalente a null .

La risposta breve è … I NULL sono strani , non si comportano veramente come ci si aspetterebbe.

Ecco un ottimo articolo su come funzionano i NULL in SQL. Penso che contribuirà a migliorare la comprensione dell’argomento. Penso che le sezioni sulla gestione dei valori nulli nelle espressioni saranno particolarmente utili per te.

http://www.oracle.com/technology/oramag/oracle/05-jul/o45sql.html

Il comportamento predefinito (ANSI) dei null all’interno di un’espressione risulterà nullo (ci sono abbastanza altre risposte con i casi di ciò).

Ci sono tuttavia alcuni casi limite e avvertenze che vorrei inserire quando si ha a che fare con MS Sql Server che non viene elencato.

  • I valori nulli all’interno di un’istruzione che raggruppa valori insieme saranno considerati uguali e raggruppati.
  • I valori nulli all’interno di un’istruzione che li ordina saranno considerati uguali.
  • I valori nulli selezionati all’interno di un’istruzione che utilizza distinti saranno considerati uguali quando si valuta l’aspetto distinto della query

In SQL Server è ansible sovrascrivere la logica dell’espressione relativa al test Null = Null specifico, utilizzando SET ANSI_NULLS OFF, che fornirà quindi l’uguaglianza tra valori nulli. Questo non è uno spostamento consigliato, ma esiste.

 SET ANSI_NULLS OFF select result = case when null=null then 'eq' else 'ne' end SET ANSI_NULLS ON select result = case when null=null then 'eq' else 'ne' end 

Ecco una soluzione rapida

ISNULL (A, 0) = ISNULL (B, 0)

0 può essere modificato in qualcosa che non può mai accadere nei tuoi dati

“È sconosciuto uguale a sconosciuto b? Non c’è modo di sapere, quindi: sconosciuto.”

La domanda era: perché il confronto produce FALSO?

Data la logica a tre valori, sarebbe sensato che il confronto producesse UNKNOWN (non FALSE). Ma SQL restituisce FALSE e non UNKNOWN.

Una delle miriadi di perversioni nel linguaggio SQL.

Inoltre, occorre tenere presente quanto segue:

Se “sconosciuto” è un valore logico nella logica ternaria, allora dovrebbe essere il caso che un confronto di uguaglianza tra due valori logici che entrambi sono (il valore per) “sconosciuto”, allora quel confronto dovrebbe produrre VERO.

Se il valore logico è esso stesso sconosciuto, allora ovviamente non può essere rappresentato mettendo lì il valore “sconosciuto”, perché ciò implicherebbe che il valore logico sia noto (essere “sconosciuto”). Cioè, come la teoria relazionale dimostra che implementare la logica a 3 valori solleva il requisito di una logica a 4 valori, che una logica a 4 valori porta alla necessità di una logica a 5 valori, ecc. Ecc. All’infinito.