EXISTS y NOT EXISTS
Compruebe eficazmente si existen filas relacionadas
EXISTS y NOT EXISTS es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de SQL Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Academy incluye 4 lecciones en total.
¿Qué es EXISTS?
El operador EXISTS comprueba si una subconsulta devuelve al menos una fila. Se evalúa como TRUE si la subconsulta produce algún resultado y como FALSE si está vacía.
A diferencia de otros operadores de subconsulta que comparan valores, EXISTS solo tiene en cuenta la presencia; no examina los datos concretos que devuelve la subconsulta.
Configuración de las tablas de ejemplo
Antes de escribir consultas con EXISTS, creemos dos tablas: customers y orders. Las usaremos durante toda la lección para explorar cómo funcionan EXISTS y NOT EXISTS en la práctica.
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100),
country VARCHAR(50)
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
amount DECIMAL(10,2),
order_date DATE
);
INSERT INTO customers VALUES
(1, 'Alice', 'US'),
(2, 'Bob', 'UK'),
(3, 'Charlie', 'US'),
(4, 'Diana', 'DE');
INSERT INTO orders VALUES
(101, 1, 250.00, '2024-01-10'),
(102, 1, 180.00, '2024-02-15'),
(103, 2, 95.00, '2024-03-01'),
(104, 3, 430.00, '2024-03-22');Sintaxis básica de EXISTS
La sintaxis básica de EXISTS consiste en colocarlo dentro de una cláusula WHERE. La subconsulta que contiene EXISTS normalmente hace referencia a una columna de la consulta externa; esto se denomina subconsulta correlacionada.
La consulta siguiente encuentra todos los clientes que han realizado al menos un pedido.
SELECT customer_id, name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);SELECT 1 dentro de EXISTS
Es posible que haya notado que la subconsulta usa SELECT 1 en lugar de seleccionar una columna real. Esto es intencional: EXISTS solo comprueba si existen filas, no qué contienen.
Usar SELECT 1 (o incluso SELECT *) no cambia el resultado, pero SELECT 1 indica claramente tanto al motor de la base de datos como a quien lee la consulta que los valores concretos no importan.
-- Both of these return the same result
SELECT name FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);
SELECT name FROM customers c
WHERE EXISTS (SELECT o.* FROM orders o WHERE o.customer_id = c.customer_id);Cómo evalúa la base de datos EXISTS
Para cada fila de la consulta externa, la base de datos ejecuta la subconsulta correlacionada. En cuanto encuentra una fila coincidente, el motor deja de buscar y marca EXISTS como TRUE; esta evaluación de cortocircuito hace que EXISTS sea muy eficiente incluso con tablas grandes.
En cambio, un JOIN construiría el conjunto completo de filas coincidentes antes de filtrar, lo que puede ser más lento cuando solo necesita saber si existe una coincidencia.
-- EXISTS short-circuits after first match
-- Efficient even when orders table has millions of rows
SELECT name, country
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
AND o.amount > 200
);NOT EXISTS: encontrar filas ausentes
NOT EXISTS es la operación inversa: devuelve TRUE cuando la subconsulta no encuentra ninguna fila coincidente. Esta es la forma estándar de SQL de responder preguntas como «¿qué clientes nunca han realizado un pedido?»
Intentar resolver esto con un JOIN normal o con NOT IN puede producir resultados incorrectos cuando intervienen valores NULL; NOT EXISTS evita completamente ese problema.
-- Customers who have NOT placed any order
SELECT customer_id, name
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);NOT EXISTS frente a NOT IN con NULL
Una ventaja fundamental de NOT EXISTS frente a NOT IN es la seguridad frente a NULL. Si la subconsulta usada por NOT IN devuelve siquiera un NULL, toda la expresión NOT IN se convierte en NULL, lo que significa que la consulta externa no devuelve ninguna fila.
NOT EXISTS no se ve afectado por este problema porque evalúa la existencia de filas, no la igualdad de valores.
-- Dangerous: if any customer_id in orders is NULL,
-- NOT IN returns zero rows!
SELECT name FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM orders);
-- Safe: NOT EXISTS handles NULLs correctly
SELECT name FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
);EXISTS con varias condiciones
La subconsulta dentro de EXISTS puede contener cualquier elemento SQL válido, incluidas varias condiciones WHERE. Esto le permite comprobar si existen filas relacionadas muy específicas; por ejemplo, clientes que realizaron un pedido superior a un determinado umbral en un mes concreto.
-- Customers who placed an order over 200 in March 2024
SELECT c.name, c.country
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
AND o.amount > 200
AND o.order_date >= '2024-03-01'
AND o.order_date < '2024-04-01'
);EXISTS en DELETE y UPDATE
EXISTS no se limita a las instrucciones SELECT. Puede usarlo en UPDATE y DELETE para modificar o eliminar filas según la existencia de datos relacionados en otra tabla.
El ejemplo siguiente elimina los pedidos pertenecientes a clientes de un país concreto.
-- Delete orders placed by US customers
DELETE FROM orders o
WHERE EXISTS (
SELECT 1
FROM customers c
WHERE c.customer_id = o.customer_id
AND c.country = 'US'
);Comparación entre EXISTS y JOIN
EXISTS y JOIN suelen poder expresar la misma pregunta, pero se comportan de forma diferente. Un JOIN multiplica las filas cuando hay varias coincidencias; EXISTS siempre devuelve cada fila externa como máximo una vez.
Cuando solo necesita saber si existe una relación, y no recuperar datos de la tabla relacionada, EXISTS resulta más claro y normalmente más rápido.
-- JOIN may return duplicate customer rows if a customer has multiple orders
SELECT DISTINCT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id;
-- EXISTS always returns each customer once
SELECT c.name
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
);NOT EXISTS para comprobaciones de calidad de datos
NOT EXISTS es una herramienta eficaz para auditar la calidad de los datos. Puede usarlo para encontrar registros huérfanos, referencias inexistentes o filas que deberían tener datos relacionados, pero no los tienen.
La consulta siguiente detecta las filas de pedidos cuyo customer_id no coincide con ninguna fila de la tabla customers, lo que indica una posible vulneración de la integridad referencial.
-- Find orders with no matching customer (orphaned records)
SELECT o.order_id, o.customer_id, o.amount
FROM orders o
WHERE NOT EXISTS (
SELECT 1
FROM customers c
WHERE c.customer_id = o.customer_id
);Comprobación rápida
Compruebe su comprensión de EXISTS y NOT EXISTS.
Resumen de la lección
En esta lección ha aprendido cómo EXISTS y NOT EXISTS le permiten comprobar la presencia o ausencia de filas relacionadas sin comparar valores directamente.
Conclusiones principales:
- EXISTS devuelve TRUE en cuanto la subconsulta encuentra una fila coincidente (evaluación de cortocircuito).
- NOT EXISTS devuelve TRUE cuando la subconsulta no encuentra ninguna fila coincidente.
- Use
SELECT 1dentro de EXISTS; los valores devueltos son irrelevantes. - NOT EXISTS es seguro frente a NULL; NOT IN no lo es. Prefiera NOT EXISTS cuando puedan aparecer valores NULL.
- EXISTS funciona en las instrucciones SELECT, UPDATE y DELETE.
- Cuando solo necesita comprobar la existencia, EXISTS suele ser más claro y rápido que un JOIN.
Preguntas frecuentes
¿La lección «EXISTS y NOT EXISTS» es gratis?
Sí — el texto completo de «EXISTS y NOT EXISTS» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de SQL Academy, actualiza a CoddyKit PRO. El curso de SQL Academy incluye 4 lecciones en total.
¿Qué aprenderé en «EXISTS y NOT EXISTS»?
Compruebe eficazmente si existen filas relacionadas Practicas SQL Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar SQL Academy?
No se requiere experiencia previa. SQL Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «EXISTS y NOT EXISTS»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de SQL Academy?
Sí. Cada lección de SQL Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Subconsultas correlacionadas
- EXISTS y NOT EXISTS
- IN frente a ANY frente a ALL
- Rendimiento de EXISTS frente a JOIN