0Pricing
SQL Academy · Lección

Anti-uniones y semi-uniones (NOT EXISTS)

Encuentre «filas de A sin coincidencia en B» (anti-unión) y «filas de A con al menos una coincidencia en B» (semi-unión) mediante EXISTS/NOT EXISTS.

Anti-uniones y semi-uniones (NOT EXISTS) es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 3 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.

Semijoin: "tiene al menos una coincidencia"

Devuelva las filas de A que tengan al menos una fila coincidente en B, pero solo las columnas de A. SQL implementa los semijoins mediante EXISTS o IN.

Semijoin con EXISTS

Usuarios que han realizado al menos un pedido:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

Semijoin con IN

El mismo resultado, con un estilo diferente:

SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders);

Por qué EXISTS suele ser mejor

EXISTS aplica cortocircuito: se detiene en la primera coincidencia de cada fila externa. IN puede materializar todo el conjunto interno. Los planificadores modernos suelen optimizar ambas opciones con el mismo plan, pero EXISTS es la opción más segura para conjuntos internos enormes.

Antijoin: "no tiene ninguna coincidencia"

Usuarios que NUNCA han realizado un pedido; hay tres formas idiomáticas:

-- NOT EXISTS (preferred):
SELECT u.* FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

-- LEFT JOIN ... IS NULL:
SELECT u.* FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;

-- NOT IN (risky with NULLs):
SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM orders);

Por qué NOT IN es arriesgado

Si la subconsulta interna contiene NULL, NOT IN devuelve NULL, y WHERE descarta las filas cuyo predicado es NULL. Resultado: cero filas. NOT EXISTS no presenta este problema.

Optimización del planificador

El PostgreSQL moderno reconoce EXISTS y NOT EXISTS como patrones de semijoin y antijoin, y puede ejecutarlos mediante hash joins:

EXPLAIN ANALYZE
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
-- → Hash Anti Join

Antijoins con varias columnas

Utilice claves compuestas:

SELECT * FROM order_items oi
WHERE NOT EXISTS (
  SELECT 1 FROM shipments s
  WHERE s.order_id = oi.order_id
    AND s.line_no  = oi.line_no
);

Semijoin con EXISTS + predicado adicional

Añada filtros a la subconsulta interna:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.user_id = u.id
    AND o.status = 'paid'
    AND o.created_at >= NOW() - INTERVAL '30 days'
);

Indexar la columna de correlación

Tanto en EXISTS como en NOT EXISTS, la subconsulta interna filtra por la clave de la fila externa. Sin un índice en esa clave, se realiza un escaneo por cada fila externa:

CREATE INDEX orders_user_id_idx ON orders(user_id);

Cuándo utilizar LEFT JOIN ... IS NULL

Para paneles que también necesitan las columnas del lado sin coincidencias, el estilo LEFT JOIN resulta natural. Para una semántica de antijoin pura, NOT EXISTS es más claro.

Más allá de SQL: filtros Bloom

Para antijoins enormes, un prefiltrado con un filtro Bloom puede ayudar. PostgreSQL admite índices bloom mediante la extensión bloom.

Resumen

Semijoin = "tiene coincidencias"; antijoin = "no tiene coincidencias".

  • EXISTS para semijoins
  • NOT EXISTS para antijoins (seguro frente a NULL)
  • Indexe la columna de correlación
  • Evite NOT IN salvo que el conjunto interno no pueda contener NULL

Comprobación rápida

Quiere obtener los usuarios que NUNCA han realizado un pedido. ¿Cuál es la opción SQL más segura e idiomática?

Preguntas frecuentes

¿La lección «Anti-uniones y semi-uniones (NOT EXISTS)» es gratis?

Sí — el texto completo de «Anti-uniones y semi-uniones (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 «Anti-uniones y semi-uniones (NOT EXISTS)»?

Encuentre «filas de A sin coincidencia en B» (anti-unión) y «filas de A con al menos una coincidencia en B» (semi-unión) mediante EXISTS/NOT EXISTS. 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 3 de 4.

¿Cuánto tiempo toma la lección «Anti-uniones y semi-uniones (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

  1. CROSS JOIN y productos cartesianos
  2. Uniones laterales (LATERAL JOIN)
  3. Anti-uniones y semi-uniones (NOT EXISTS)
  4. Optimización del rendimiento de uniones entre varias tablas
← Volver a SQL Academy