2010-11-18 14 views
5

Ho creato alcune query e non riesco a capire perché i risultati non sono quelli che mi aspettavo.Utilizzo di predicati NON in SQL

Non capisco perché Query II e III non restituiscano gli stessi risultati. Mi aspetto che la query II restituisca tutte le righe non selezionate dalla query I.

Mi sarei aspettato che Query II e III dessero gli stessi risultati. Secondo me i risultati di III sono quelli giusti.

Sono sicuro che mi manca qualcosa, semplicemente non so cosa.

L'esempio:

Tabella:

CREATE TABLE [dbo].[TestTable](
[TestTableId] [int] NOT NULL, 
    [ValueA] [int] NULL, 
[ValueB] [int] NULL 
) ON [PRIMARY] 

dati:

TestTableId ValueA ValueB 
1  10  5 
2  20  5 
3  10  NULL 
4  20  NULL 
5  NULL  10 
6  10  10 
7  NULL  NULL 

Query:

Tutti i record: select * from TabellaProva

I. Una query di selezione:

select * from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5 

Risultato:

TestTableId ValueA ValueB 
1   10 5 
2   20 5 

II. La stessa query, ma come non

select * from TestTable 
where NOT ((ValueA = 10 or ValueA = 20) AND ValueB = 5) 

Risultato:

TestTableId ValueA ValueB 
5   NULL 10 
6   10 NULL 

III. La stessa query come il secondo (penserei)

select * from TestTable where TestTable.TestTableId not in 
    (select TestTableId from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5) 

Risultato:

TestTableId ValueA ValueB 
3   10 NULL 
4   20 NULL 
5   NULL 10 
6   10 10 
7   NULL NULL 

risposta

5

NULL sono creature divertenti. Essi rispondere "Non lo so" per entrambe le seguenti domande:

Are you 5? (... WHERE ValueB = 5) 

e

Are you Not 5? (... WHERE NOT ValueB = 5) 

che si traduce in valori NULL di essere esclusi da entrambe le query, come l'avete trovato.

si deve porre la domanda in un modo che tenga conto in modo esplicito per i valori null:

... WHERE (ValueB IS NULL OR NOT ValueB = 5) ... 
+0

'NULL = 5' restituisce" UNKNOWN "(anziché" no "). – onedaywhen

+0

Ero un po 'metaforico. Il punto è che una riga in cui ValueB è NULL verrà esclusa da entrambi. – BradC

+0

@onedaywhen - Modificato il mio post in modo leggermente più preciso in base al tuo commento. – BradC

2

Quando si utilizza NOT, NULL valori sono una situazione particolare.

A NULL è un valore sconosciuto. SQL non può dire se è NOT a 12, ma può dire se è a a 12.

Un buon esempio:

Sei a una festa. Conosci 2 dei 12 nomi di persone presenti nella stanza, entrambi si chiamano John. Puoi dirmi chi sono i "John". È impossibile dirmi chi è "Non Jack" oltre ai 2 "Giovanni". Per SQL, quelle altre 10 persone nella stanza hanno un nome di NULL.