A menudo se requiere formular consultas en las que los criterios de filtrado se definen dinámicamente: la lista de valores la establece el usuario de la interfaz, y los valores omitidos (NULL) también deben poder incluirse o no en el resultado. Tal consulta debe funcionar rápidamente con grandes volúmenes y ser correcta desde el punto de vista semántico de SQL.
La combinación incorrecta de las condiciones IN, NOT IN y la verificación de NULL lleva a resultados inesperados porque en SQL la expresión "NULL IN (...)" siempre devuelve UNKNOWN, y "NOT IN" puede llevar a un resultado vacío si al menos uno de los elementos de la lista es NULL. El rendimiento en grandes datos con una condición mal escrita puede caer drásticamente.
La combinación correcta se ve así:
SELECT * FROM sales WHERE region IN ('Moscú','Samara') OR region IS NULL;
SELECT * FROM sales WHERE (region NOT IN ('Moscú','Samara') OR region IS NULL);
SELECT * FROM sales WHERE region NOT IN ('Moscú','Samara') AND region IS NOT NULL;
Características clave:
¿Qué sucederá si se verifica "WHERE field NOT IN ('a', NULL)"?
El resultado siempre será vacío, ya que cualquier fila se compara con NULL en la lista, lo que da UNKNOWN y filtra todo.
Ejemplo de código:
SELECT * FROM test WHERE name NOT IN ('Iván', NULL);
¿Dará "IN (NULL,...)" valor para filas con NULL?
No. La expresión NULL IN (...) siempre devuelve UNKNOWN, no TRUE.
¿Cómo acelerar el filtrado por una gran lista de valores?
Usar índices y preferiblemente aplicar JOIN con una tabla temporal, si la lista es grande (cientos/miles de valores) — eso acelera el filtrado en comparación con un largo IN.
En un informe analítico se aplicó "WHERE city NOT IN ('Londres', field_2, NULL)". Resultado: completamente vacío, nadie pudo entender durante mucho tiempo la razón de las filas perdidas.
Ventajas:
Desventajas:
En CRM se seleccionó una lista de regiones de clientes y se añadió un botón adicional "Incluir valores no completados". Lógica de filtrado:
... WHERE city IN ('SPB','NNov') OR city IS NULL
Ventajas:
Desventajas: