2010-11-18 13 views
5

He creado algunas consultas y no puedo entender por qué los resultados no son los que esperaba.Usando predicados NOT en SQL

No entiendo por qué Query II y III no devuelven los mismos resultados. Esperaría que la consulta II devuelva todas las filas no seleccionadas por Query I.

Hubiera esperado que Query II y III dieran los mismos resultados. En mi opinión, los resultados de III son los correctos.

Estoy seguro de que extraño algo, simplemente no sé qué.

El ejemplo:

Tabla:

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

datos:

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

Consultas:

Todos los registros: seleccionar * de TestTable

I. Una consulta de selección:

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

Resultado:

TestTableId ValueA ValueB 
1   10 5 
2   20 5 

II. La misma consulta pero como NOT

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

Resultado:

TestTableId ValueA ValueB 
5   NULL 10 
6   10 NULL 

III. La misma consulta que la segunda (yo creo)

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

Resultado:

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

Respuesta

5

NULL son criaturas divertidas. Ellos responderán "no sé" a las dos preguntas siguientes:

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

y

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

que se traduce en valores NULL siendo excluidos de ambas consultas, como lo encontró.

Usted tiene que hacer la pregunta de una manera que da cuenta de forma explícita para los nulos:

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

'NULL = 5' se evalúa como' UNKNOWN' (en lugar de "no"). – onedaywhen

+0

Estaba siendo un poco metafórico. El punto es que una fila donde ValueB es NULL se excluirá de ambos. – BradC

+0

@onedaywhen - Edité mi publicación para ser un poco más preciso en función de su comentario. – BradC

2

Al utilizar NOT, NULL valores son una situación especial.

A NULL es un valor desconocido. SQL no puede decir si es NOT a 12, pero puede decir si es a 12.

Un buen ejemplo:

Estás en una fiesta. Usted sabe que 2 de los 12 nombres de personas en la sala, ambos se llaman Juan. Puedes decirme quienes son los "John". Usted no puede decirme quién es "No Jack" además de los 2 "John" s. Para SQL, esas otras 10 personas en la sala tienen un nombre de NULL.

Cuestiones relacionadas