Encontrar filas sin coincidencia (anti-join)
Use el patrón LEFT JOIN / IS NULL para encontrar registros huérfanos y datos faltantes
Encontrar filas sin coincidencia (anti-join) es una lección gratuita de Coding Interview Prep 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 Coding Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Coding Interview Prep incluye 4 lecciones en total.
La pregunta sobre el anti-join
Una de las preguntas más frecuentes sobre joins externos es: «Encuentre los clientes que nunca han hecho un pedido». O bien: «Muestre los productos que nunca se han vendido», o «los pedidos que no tienen un cliente coincidente».
Todas comparten una misma estructura: filas de una tabla que no tienen coincidencia en otra. La forma idiomática es el anti-join, basado en un LEFT JOIN seguido de un filtro IS NULL.
La idea central
Parta de un LEFT JOIN: conserva todas las filas de la izquierda, y las filas izquierdas sin coincidencia reciben NULL en las columnas de la tabla derecha.
Por tanto, las filas sin coincidencia son exactamente aquellas en las que una columna de la tabla derecha es NULL. Filtre por esa condición y aislará las filas sin coincidencia. Ese es todo el truco.
Construcción del patrón
Este es el anti-join canónico para encontrar clientes sin pedidos. Léalo en dos pasos: LEFT JOIN conserva todos los clientes y luego WHERE o.customer_id IS NULL conserva solo los que no tienen coincidencia.
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
WHERE o.customer_id IS NULL;
-- only customers with zero ordersPor qué funciona, paso a paso
Recórralo con nuestros datos, en los que Carol no tiene pedidos:
- LEFT JOIN produce Alice (x2), Bob (x1) y Carol, con las columnas de la derecha en NULL.
WHERE o.customer_id IS NULLdescarta a Alice y Bob (sus columnas de la derecha tienen valores reales).- Solo sobrevive la fila de Carol, la fila con NULL sintetizados.
El filtro se ejecuta después del join, por lo que ve esos NULL y selecciona precisamente las filas huérfanas.
Elija la columna correcta que comprobar
Compruebe una columna de la tabla derecha que nunca pueda ser NULL legítimamente en una coincidencia real, idealmente la clave de unión o la clave primaria.
Si comprueba una columna anulable de la derecha, como o.shipped_at, también encontraría pedidos que existen pero aún no se han enviado, lo cual sería incorrecto. Comprobar o.customer_id (la clave de unión) u o.id (su clave primaria) garantiza que NULL significa «ninguna fila coincidió».
-- SAFE: join key / primary key
WHERE o.id IS NULL
-- RISKY: a nullable data column
WHERE o.shipped_at IS NULL -- catches unshipped too!Anti-join frente a NOT IN
Los entrevistadores comparan el anti-join con NOT IN. Parecen equivalentes, pero se comportan de forma distinta con NULL.
Si la subconsulta devuelve cualquier NULL, NOT IN no devuelve ninguna fila, un conocido error silencioso. El anti-join LEFT JOIN / IS NULL no se ve afectado por este problema.
-- DANGEROUS if any customer_id is NULL
SELECT id, name FROM customers
WHERE id NOT IN (SELECT customer_id FROM orders);
-- SAFE anti-join, same intent
SELECT c.id, c.name FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;Anti-join frente a NOT EXISTS
La otra alternativa equivalente es NOT EXISTS con una subconsulta correlacionada. También gestiona correctamente los NULL y a menudo ofrece el mismo rendimiento.
Las tres opciones (LEFT JOIN/IS NULL, NOT EXISTS y NOT IN) pueden expresar anti-joins, pero en una entrevista prefiera LEFT JOIN/IS NULL o NOT EXISTS porque son seguras frente a NULL. Mencionar el problema de NOT IN le hará ganar puntos.
SELECT c.id, c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);Un error frecuente
Un error frecuente consiste en poner la condición de ausencia de coincidencia en la cláusula ON en lugar de WHERE.
Escribir ... ON o.customer_id = c.id AND o.id IS NULL no filtra el resultado; simplemente cambia qué se considera una coincidencia, y todos los clientes siguen sobreviviendo al LEFT JOIN. La comprobación IS NULL debe estar en WHERE, aplicada después del join. Analizaremos este problema en detalle en la siguiente lección.
Encontrar filas secundarias huérfanas
El patrón también funciona en la otra dirección. Para encontrar pedidos que hacen referencia a un cliente inexistente (huérfanos, una comprobación de integridad de datos), conserve orders y compruebe que el lado de los clientes sea NULL.
SELECT o.id AS order_id, o.customer_id
FROM orders o
LEFT JOIN customers c
ON c.id = o.customer_id
WHERE c.id IS NULL;
-- orders pointing to a non-existent customerContar los huérfanos
A menudo solo se pide un recuento: «¿Cuántos clientes nunca han hecho un pedido?» Envuelva el anti-join o cuente directamente.
Como el anti-join ya devuelve una fila por huérfano, un COUNT(*) simple sobre él es correcto aquí: hay exactamente una fila por cada cliente sin coincidencia.
SELECT COUNT(*) AS never_ordered
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;Plantilla reutilizable
Memorice este esquema de tres líneas; resuelve una gran cantidad de preguntas de entrevista:
FROM keep_table kLEFT JOIN other o ON o.fk = k.idWHERE o.id IS NULL
Intercambie las tablas y las claves para encontrar productos no vendidos, tickets sin asignar, usuarios sin inicios de sesión o cualquier caso descrito como «X sin un Y coincidente».
Comprobación rápida
Necesita los productos que nunca han aparecido en order_items.
Resumen
El anti-join encuentra filas sin coincidencia: LEFT JOIN seguido de WHERE right_key IS NULL.
- Compruebe la clave de unión o la clave primaria, nunca una columna de datos anulable.
- La comprobación
IS NULLdebe estar enWHERE, no enON. - Es equivalente a
NOT EXISTS; prefiera esta opción aNOT IN, que falla con NULL. - Invierta las tablas para encontrar filas secundarias huérfanas.
Una plantilla, muchas preguntas: «X sin un Y coincidente».
Preguntas frecuentes
¿La lección «Encontrar filas sin coincidencia (anti-join)» es gratis?
Sí — el texto completo de «Encontrar filas sin coincidencia (anti-join)» 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 Coding Interview Prep, actualiza a CoddyKit PRO. El curso de Coding Interview Prep incluye 4 lecciones en total.
¿Qué aprenderé en «Encontrar filas sin coincidencia (anti-join)»?
Use el patrón LEFT JOIN / IS NULL para encontrar registros huérfanos y datos faltantes Practicas Coding Interview Prep 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 Coding Interview Prep?
No se requiere experiencia previa. Coding Interview Prep 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 «Encontrar filas sin coincidencia (anti-join)»?
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 Coding Interview Prep?
Sí. Cada lección de Coding Interview Prep 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
- LEFT JOIN y conservación de filas sin coincidencia
- Semántica de RIGHT y FULL OUTER JOIN
- Encontrar filas sin coincidencia (anti-join)
- La trampa de WHERE en un outer join