Pregunta 1¿Cuál es la descripción correcta de WHERE EXISTS (SELECT 1 FROM sales sale WHERE sale.emp_id = emp.emp_id)?
EXISTS y subconsultas correlacionadas
Aprende SQL EXISTS y las subconsultas correlacionadas: EXISTS / NOT EXISTS, cómo evitar de forma segura la trampa de NOT IN + NULL con EXISTS y cuándo elegir EXISTS frente a IN — practicado con datos de empleados y ventas, todo ejecutándose en vivo en tu navegador.
Datos usados en este artículo — employee / sales / department
EXISTS es una subconsulta que comprueba solo si existe al menos una fila que coincide, y la usas de forma muy parecida a IN.
En este artículo recorrerás los fundamentos de EXISTS / NOT EXISTS, cómo evitar de forma segura la trampa de NOT IN + NULL escribiéndola con EXISTS, y cómo elegir entre EXISTS e IN según la legibilidad.
El material son tres tablas de datos de empleados.
Usando employee (30 empleados), sales (50 líneas de venta) y department (6 departamentos), extraerás "empleados con / sin ventas" y "departamentos sin empleados".
EXISTS / NOT EXISTS — solo comprobar si existe una fila
WHERE EXISTS (SELECT ... ) es verdadero si la subconsulta devuelve aunque sea una fila, y falso si no devuelve ninguna fila.
Lo que selecciona la subconsulta no afecta al resultado, así que por convención escribes SELECT 1 (el valor no se usa — solo te importa si existe una fila).
La forma básica es una subconsulta correlacionada que referencia una columna de la consulta principal dentro del EXISTS.
"Empleados con ventas" es WHERE EXISTS (SELECT 1 FROM sales sale WHERE sale.emp_id = emp.emp_id), y "empleados sin ventas" es la negación de eso, NOT EXISTS.
EXISTS deja de evaluar en cuanto encuentra una fila, lo que lo hace adecuado para comprobaciones de existencia.
-- EXISTS: empleados con ventas
SELECT emp.emp_id, emp.name
FROM employee emp
WHERE EXISTS (
SELECT 1 FROM sales sale WHERE sale.emp_id = emp.emp_id
)
ORDER BY emp.emp_id;
La trampa de NOT IN + NULL — EXISTS es seguro
Si escribes "filtrado negativo" con NOT IN, el resultado puede salir como 0 filas cuando se mezcla un NULL en el lado de la subconsulta.
x NOT IN (1, 2, NULL) se evalúa como "x no es 1, no es 2 y no es NULL", pero x <> NULL nunca se vuelve verdadero y siempre es NULL (desconocido), así que el NOT IN completo nunca se vuelve verdadero.
El razonamiento completo se explica en Subconsultas ① (la trampa de NOT IN + NULL).
Como employee.dept_id mezcla NULL, escribir "departamentos sin empleados" como WHERE dept_id NOT IN (SELECT dept_id FROM employee) hace que Legal (un departamento sin ningún empleado), que debería estar ahí, desaparezca y el resultado salga como 0 filas.
NOT EXISTS solo mira si existe una fila y no se ve afectado por NULL, así que en esta situación NOT EXISTS devuelve el resultado correcto.
-- Trampa: una subconsulta que contiene NULL + NOT IN sale como 0 filas
SELECT dept_id, dept_name
FROM department
WHERE dept_id NOT IN (SELECT dept_id FROM employee);
-- → 0 filas porque employee.dept_id contiene NULL
-- Seguro: NOT EXISTS no se ve afectado por NULL
SELECT d.dept_id, d.dept_name
FROM department d
WHERE NOT EXISTS (
SELECT 1 FROM employee emp WHERE emp.dept_id = d.dept_id
);
Elige EXISTS por legibilidad
EXISTS solo mira si existe una fila, así que es seguro incluso cuando hay NULL, pero escribir una subconsulta correlacionada puede hacer que parezca más largo que IN.
Para una comprobación de existencia simple hay situaciones en las que IN se lee mejor, y en el trabajo real eliges según el contexto.
Por otro lado, para una negación como NOT IN donde NULL rompe el resultado, o cuando quieres juzgar de forma fiable solo si existe una fila, EXISTS / NOT EXISTS es la opción segura.
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2Cuando un NULL puede mezclarse en el lado de la subconsulta, ¿qué problema puede ocurrir si escribes el filtrado negativo con NOT IN?
Pregunta 3¿Cuál es una forma adecuada de decidir entre EXISTS e IN?