2010-04-02 7 views
5

pasé algún tiempo tratando de averiguar por qué esta consulta no está tirando de los resultados que esperaba:¿Por qué "no existe" obra de consulta SQL y "no en" ¿no

SELECT * FROM NGS WHERE ESPSSN NOT IN (SELECT SSN FROM CENSUS) 

finalmente he intentado escribir la consulta de otra forma y este terminamos conseguir los resultados esperados:

SELECT * FROM NGS n WHERE NOT EXISTS (SELECT * FROM CENSUS WHERE SSN = n.ESPSSN) 

la primera consulta parece más apropiado y "correcta". Admitidos "en" y "no en" todo el tiempo para selecciona similares y nunca he tenido un problema que yo sepa.

Respuesta

11

Si se escribe el azúcar sintáctico, x not in (1,2,3) se convierte en:

x <> 1 AND x <> 2 AND x <> 3 

lo tanto, si la columna de la ssn contiene un valor nulo, la primera consulta es el equivalente a:

WHERE ESPSSN <> NULL AND ESPSSN <> ... 

El resultado de la comparación con NULL es desconocida, por lo que la consulta no devolverá nada.

+0

¡Buena llamada! Acabo de verificar y hay un valor nulo en la tabla. Reescribiendo la consulta para SELECCIONAR * FROM NGS DONDE ESPSSN NO IN (SELECCIONAR ISNULL (SSN, '') DESDE CENSO) me dio el valor esperado. Me pregunto cuál debería usar? – Josh

+0

@Josh: valor predeterminado para 'no existe' porque no sufre el' null' gotcha. Pero si usted tiene problemas de rendimiento, puede ser vale la pena examinar el plan de consulta para ambas opciones – Andomar

+0

@ Josh, @Andomar: El ISNULL invalidará el uso de cualquier índice que puede haber sido usado antes – gbn

2

Como Andomar Dicho esto, ten cuidado de valores NULL cuando se utiliza NOT IN

en cuenta también que una consulta utilizando el predicado NOT IN siempre será realizar escaneos completos de tabla anidadas, mientras que una consulta utilizando NOT EXISTS puede utilizar un índice dentro de la sub-consulta , y será mucho más rápido como resultado.

+0

Es bueno saberlo. Gracias. – Josh

Cuestiones relacionadas