Manual de campo · trampas de SQL
NOT IN contra una lista con un solo NULL descarta la consulta entera sin avisar. Es el peor fallo posible: no revienta, da tranquilidad.
Cualquier antijoin (buscar lo que falta, lo que no coincide, lo que no se registró) escrito con NOT IN sobre una columna que admite NULL. Es una pregunta clásica de entrevista de SQL porque parece inofensiva.
Mal: NOT IN con un NULL en la lista
SELECT nombre
FROM personas
WHERE nombre NOT IN (
SELECT nombre FROM coartadas
);
-- coartadas tiene una fila con nombre NULL (un recibo sin firma):
-- la consulta entera devuelve cero filas, aunque haya sospechosos sin coartada
Bien: NOT EXISTS, que no le teme a los nulos
SELECT nombre
FROM personas p
WHERE NOT EXISTS (
SELECT 1 FROM coartadas c WHERE c.nombre = p.nombre
);
-- o, filtrando el NULL dentro de la propia lista:
WHERE nombre NOT IN (
SELECT nombre FROM coartadas WHERE nombre IS NOT NULL
)
x NOT IN (a, b, NULL) no es una lista con un hueco: es x<>a AND x<>b AND x<>NULL, y esa última comparación da NULL, no verdadero ni falso. Una conjunción con un NULL nunca da verdadero, así que ninguna fila pasa el filtro, sin importar cuántos nombres falten de verdad. NOT EXISTS no compara con la lista entera: pregunta fila por fila, y un NULL en la subconsulta no contamina a las demás. La otra salida es quitar el NULL antes de que llegue al NOT IN, pero eso obliga a acordarse cada vez; NOT EXISTS es la opción segura por defecto.
Esta trampa está escondida en un caso de verdad, con datos de verdad.
Jugar el caso 1 gratis →