¿Por qué NO IN con un conjunto que contiene NULL siempre devuelve FALSE / NULL?


21

Tuve una consulta (para Postgres e Informix) con una NOT INcláusula que contiene una subconsulta que en algunos casos devolvió NULLvalores, lo que provocó que esa cláusula (y la consulta completa) no devolvieran nada.

¿Cuál es la mejor manera de entender esto? Pensé NULLen algo sin valor y, por lo tanto, no esperaba que la consulta fallara, pero obviamente esa no es la forma correcta de pensar NULL.

Respuestas:


29

Lógica booleana - o lógica de tres valores

  • IN es la abreviatura de una serie de condiciones OR
  • x NOT IN (1, 2, NULL) es lo mismo que NOT (x = 1 OR x = 2 OR x = NULL)
  • ... es lo mismo que x <> 1 AND x <> 2 AND x <> NULL
  • ... es lo mismo que true AND true AND unknown**
  • ... = unknown**
  • ... que es casi lo mismo que falseen este caso ya que no pasará la WHEREcondición **

Ahora, esta es la razón por la cual la gente usa EXISTS+ en NOT EXISTSlugar de IN+ NOT IN. También vea El uso de la lógica NOT en relación con los índices para obtener más información.

** Nota: unknownes lo mismo que falseal final de una expresión en una WHEREcondición.
Mientras se evalúa la expresión, entonces se desconoce
Ver el comentario de @ kgrittn a continuación para saber por qué


10
Incluso con la aclaración es técnicamente incorrecto, y de una manera que podría quemar a alguien. Por ejemplo, si considera x <> NULLque está resolviendo FALSE, esperaría NOT (x <> NULL)evaluar TRUEy no lo hace. Ambos evalúan a UNKNOWN. El truco es que se selecciona una fila solo si la WHEREcláusula (si está presente) se evalúa como TRUE: una fila se omite si la cláusula se evalúa como FALSEo UNKNOWN. Este comportamiento (en general, y para el NOT INpredicado en particular) es obligatorio por el estándar SQL.
kgrittn

Tampoco NULL NOT IN (some_subquery)debe devolver la fila exterior, excepto si some_subqueryno devuelve ninguna fila. Es por eso que el plan de ejecución cuando ambas columnas son nulas puede ser considerablemente más costoso. Ejemplo de SQL Server
Martin Smith
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.