Qualcuno potrebbe spiegare il seguente comportamento in SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
Qualcuno potrebbe spiegare il seguente comportamento in SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
Risposte:
<>
è SQL-92 standard; !=
è il suo equivalente. Entrambi valutano i valori, il che NULL
non lo è - NULL
è un segnaposto per dire che c'è l'assenza di un valore.
Ecco perché è possibile utilizzare IS NULL
/ solo IS NOT NULL
come predicati per tali situazioni.
Questo comportamento non è specifico di SQL Server. Tutti i dialetti SQL conformi agli standard funzionano allo stesso modo.
Nota : per confrontare se il valore non è nullo , si utilizza IS NOT NULL
, mentre per confrontare con valore non nullo , si utilizza <> 'YOUR_VALUE'
. Non posso dire se il mio valore è uguale o meno uguale a NULL, ma posso dire se il mio valore è NULL o NOT NULL. Posso confrontare se il mio valore è diverso da NULL.
!=
fino a ~ 9i a quanto ho capito, il che ha portato molta sintassi ANSI-92. La mia convinzione è che MySQL sia simile, iniziando il supporto in 4.x.
!=
potrebbe essere stato incluso in una specifica successiva in alternativa a <>
. Non ho le mani su nuove specifiche, quindi non posso dirlo con certezza.
WHERE MyColumn != NULL
o WHERE MyColumn = NULL
deterministico? O in altre parole, è garantito che restituisca sempre 0 righe, non importa se MyColumn
è nullable nel database o no?
!=
valuta solo i valori, fare qualcosa del genere WHERE MyColumn != 'somevalue'
non restituirà i record NULL.
NULL non ha valore e quindi non può essere confrontato utilizzando gli operatori di valore scalare.
In altre parole, nessun valore può mai essere uguale a (o non uguale a) NULL perché NULL non ha valore.
Quindi, SQL ha speciali predicati IS NULL e IS NOT NULL per la gestione di NULL.
'a' != null
NON restituire un valore ( true
/ 1
) sia contro intuitivo e mi sorprende di tanto in tanto! Avrei pensato che "un certo valore rispetto a nessun valore" sarebbe sempre "non uguale", ma forse sono solo io?!?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
assegnare comunemente una costante se è un valore NULL, purché si fornisca un tipo di dati appropriato per il valore sentinella x (in questo caso una stringa / carattere). Questa è la sintassi TSQL ma Oracle e altri motori hanno funzionalità simili.
Si noti che questo comportamento è il comportamento predefinito (ANSI).
Se tu:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Otterrai risultati diversi.
SET ANSI_NULLS OFF
apparentemente andrà via in futuro ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
è OFF, gli operatori di confronto Equals (=) e Not Equal To (<>) non seguono lo standard ISO. Un'istruzione SELECT che utilizza WHERE column_name = NULL
restituisce le righe con valori null in nome_colonna. WHERE column_name <> NULL
Un'istruzione SELECT che utilizza restituisce le righe con valori non nulli nella colonna. Inoltre, un'istruzione SELECT che utilizza WHERE column_name <> XYZ_value
restituisce tutte le righe che non sono XYZ_value e che non sono NULL. IMHO, quest'ultima affermazione sembra un po 'strana nella sua esclusione di valori nulli dai risultati!
In SQL, tutto ciò che valuti / calcoli con NULL
risultati in UNKNOWN
Ecco perché SELECT * FROM MyTable WHERE MyColumn != NULL
o SELECT * FROM MyTable WHERE MyColumn <> NULL
ti dà 0 risultati.
Per fornire un controllo per i NULL
valori, viene fornita la funzione isNull.
Inoltre, è possibile utilizzare l' IS
operatore come utilizzato nella terza query.
Spero che questo ti aiuti.
L'unico test per NULL è IS NULL o IS NOT NULL. Test per l'uguaglianza è senza senso perché per definizione non si sa quale sia il valore.
Ecco un articolo di Wikipedia da leggere:
Noi usiamo
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
per restituire tutte le righe in cui MyColumn è NULL o tutte le righe in cui MyColumn è una stringa vuota. Per molti un "utente finale", il problema NULL vs. stringa vuota è una distinzione senza necessità e punto di confusione.
Semplicemente non vedo la ragione funzionale e senza soluzione di continuità per cui i null non siano paragonabili ad altri valori o altri null, perché possiamo chiaramente confrontarli e dire che sono uguali o meno nel nostro contesto. È divertente. Solo a causa di alcune conclusioni logiche e coerenza, dobbiamo preoccuparci costantemente di ciò. Non è funzionale, rendilo più funzionale e lascia che filosofi e scienziati concludano se è coerente o meno e contiene "logica universale". :) Qualcuno potrebbe dire che è a causa di indici o qualcos'altro, dubito che quelle cose non possano essere fatte per supportare valori null come i valori. È come confrontare due bicchieri vuoti, uno è un bicchiere di vite e l'altro è un bicchiere di birra, non stiamo confrontando i tipi di oggetti ma i valori che contengono, gli stessi che potresti confrontare int e varchar, con null ' È ancora più semplice, è nulla e ciò che due cose hanno in comune, sono le stesse, chiaramente paragonabili a me e a tutti gli altri che scrivono sql, perché rompiamo costantemente quella logica confrontandole in modi strani a causa di alcuni standard ANSI. Perché non usare il potere del computer per farlo per noi e dubito che rallenterebbe le cose se tutto ciò che è correlato fosse costruito pensando a quello. "Non è nulla, non è niente", non è Apple, è un apfel, dai ... Funzionalmente è tuo amico e qui c'è anche la logica. Alla fine l'unica cosa che conta è la funzionalità e l'uso di null in quel modo porta più o meno funzionalità e facilità d'uso. È più utile? perché rompiamo costantemente questa logica confrontandola in modi strani a causa di alcuni standard ANSI. Perché non usare il potere del computer per farlo per noi e dubito che rallenterebbe le cose se tutto ciò che è correlato fosse costruito pensando a quello. "Non è nulla, non è niente", non è Apple, è un apfel, dai ... Funzionalmente è tuo amico e qui c'è anche la logica. Alla fine l'unica cosa che conta è la funzionalità e l'uso di null in quel modo porta più o meno funzionalità e facilità d'uso. È più utile? perché rompiamo costantemente questa logica confrontandola in modi strani a causa di alcuni standard ANSI. Perché non usare il potere del computer per farlo per noi e dubito che rallenterebbe le cose se tutto ciò che è correlato fosse costruito pensando a quello. "Non è nulla, non è niente", non è Apple, è un apfel, dai ... Funzionalmente è tuo amico e qui c'è anche la logica. Alla fine l'unica cosa che conta è la funzionalità e l'uso di null in quel modo porta più o meno funzionalità e facilità d'uso. È più utile? s non è apple è apfel, dai ... Funzionalmente è tuo amico e qui c'è anche la logica. Alla fine l'unica cosa che conta è la funzionalità e l'uso di null in quel modo porta più o meno funzionalità e facilità d'uso. È più utile? s non è apple è apfel, dai ... Funzionalmente è tuo amico e qui c'è anche la logica. Alla fine l'unica cosa che conta è la funzionalità e l'uso di null in quel modo porta più o meno funzionalità e facilità d'uso. È più utile?
Considera questo codice:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Quanti di voi sanno cosa restituirà questo codice? Con o senza NOT restituisce 0. Per me questo non è funzionale ed è confuso. In c # è tutto come dovrebbe essere, le operazioni di confronto restituiscono valore, logicamente anche questo produce valore, perché in caso contrario non c'è nulla da confrontare (tranne. Niente :)). Hanno appena "detto": qualsiasi cosa rispetto a null "restituisce" 0 e questo crea molte soluzioni alternative e mal di testa.
Questo è il codice che mi ha portato qui:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Devo solo confrontare se due campi (in cui) hanno valori diversi, potrei usare la funzione, ma ...
NULL Non può essere confrontato con alcun valore utilizzando gli operatori di confronto. NULL = NULL è falso. Null non è un valore. L'operatore IS è appositamente progettato per gestire i confronti NULL.
null = null
dove si potrebbe usare 1=0
in qualche query ad hoc. E se si lamentano, lo cambio in null != null
:)
Vecchia domanda, ma quanto segue potrebbe offrire qualche dettaglio in più.
null
non rappresenta alcun valore o un valore sconosciuto. Non specifica perché non vi è alcun valore, il che può portare ad alcune ambiguità.
Supponiamo di eseguire una query come questa:
SELECT *
FROM orders
WHERE delivered=ordered;
cioè, stai cercando righe in cui le date ordered
e delivered
sono uguali.
Cosa ci si aspetta quando una o entrambe le colonne sono nulle?
Poiché almeno una delle date è sconosciuta, non puoi aspettarti di dire che le 2 date sono uguali. Questo è anche il caso in cui entrambe le date sono sconosciute: come possono essere uguali se non sappiamo nemmeno cosa siano?
Per questo motivo, qualsiasi espressione trattata null
come un valore deve fallire. In questo caso, non corrisponderà. Questo è anche il caso se provi quanto segue:
SELECT *
FROM orders
WHERE delivered<>ordered;
Ancora una volta, come possiamo dire che due valori non sono gli stessi se non sappiamo cosa siano.
SQL ha un test specifico per i valori mancanti:
IS NULL
In particolare non sta confrontando i valori, ma piuttosto cerca valori mancanti .
Infine, per quanto riguarda l' !=
operatore, per quanto ne so, in realtà non rientra in nessuno degli standard, ma è ampiamente supportato. È stato aggiunto per far sentire i programmatori di alcune lingue più a loro agio. Francamente, se un programmatore ha difficoltà a ricordare quale lingua stanno usando, stanno iniziando male.
NULL
intendiamo che stiamo confrontando un valore con 'avere un NULL
valore', non il valore con "il valore indeterminato che il sottostante NULL
sta avendo? ma che non sappiamo ", che ovviamente non potremo mai sapere. Ciò faciliterebbe davvero le cose.
IS NULL
sia molto più arduo che scrivere = NULL
. Penso che sarebbe più coerente se WHERE columnA = columnB
avesse la stessa interpretazione di WHERE columnA = NULL
, piuttosto che considerare quest'ultimo come un caso speciale. Ricorda che nonNULL
è un valore. Nei linguaggi di programmazione in cui è legittimo testarlo è perché ha un significato diverso; non rappresenta qualcosa di sconosciuto, ma un ripristino intenzionale di un valore. Non così con SQL. variable == null
null
IS NULL
AND =NULL
nel tuo ultimo esempio. Ma dai un'occhiata all'ultimo di Hover. Sono stanco di sperimentarlo ancora e ancora, dover fare un sacco di ¿inutili? controllo extra ...
Vorrei suggerire questo codice che ho creato per scoprire se c'è un cambiamento in un valore,
i
essendo il nuovo valore ed d
essendo il vecchio (anche se l'ordine non ha importanza). Del resto, una modifica da valore a null o viceversa è una modifica, ma da null a null non lo è (ovviamente, dal valore a un altro valore è una modifica ma dal valore allo stesso non lo è).
CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
@i sql_variant,
@d sql_variant
)
RETURNS bit
AS
BEGIN
DECLARE @in bit = 0, @dn bit = 0
if @i is null set @in = 1
if @d is null set @dn = 1
if @in <> @dn
return 0
if @in = 1 and @dn = 1
return 1
if @in = 0 and @dn = 0 and @i = @d
return 1
return 0
END
Per usare questa funzione, puoi
declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)
---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp
---- where equal ----
select *,'equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 1
---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 0
I risultati sono:
---- in select ----
a b =
1 1 1
1 2 0
1 NULL 0
NULL 1 0
NULL NULL 1
---- where equal ----
1 1 equal
NULL NULL equal
---- where not equal ----
1 2 not equal
1 NULL not equal
NULL 1 not equal
L'uso di sql_variant lo rende compatibile per vari tipi
NULL non è niente ... è sconosciuto. NULL non equivale a nulla. Ecco perché devi usare la frase magica IS NULL invece di = NULL nelle tue query SQL
Puoi fare riferimento a questo: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
che sia nelle specifiche 92 ma la maggior parte dei fornitori supporta!=
e / o è inclusa in una specifica successiva come 99 o 03.