Anti join: filas sin pareja
IntermedioUn anti join devuelve las filas de una tabla que no tienen pareja en otra: clientes sin pedidos, productos sin ventas. La forma más segura es NOT EXISTS; LEFT JOIN … WHERE b.clave IS NULL es equivalente.
Sintaxis
SELECT a.*
FROM tabla_a AS a
WHERE NOT EXISTS (
SELECT 1 FROM tabla_b AS b WHERE b.clave = a.clave
);Ejemplo
SELECT c.id, c.full_name, c.city
FROM customers AS c
WHERE c.country = 'UY'
AND NOT EXISTS (
SELECT 1
FROM orders AS o
WHERE o.customer_id = c.id
)
ORDER BY c.id
LIMIT 5;Resultado
| id | full_name | city |
|---|---|---|
| 364 | Benjamín Mamani | Paysandú |
| 373 | Benjamín Mamani | Punta del Este |
| 729 | Paula Castro | Salto |
| 780 | Mateo González | Salto |
| 1183 | Carolina Ferreira | Punta del Este |
Cómo leerlo
Son clientes uruguayos registrados que nunca hicieron un pedido. NOT EXISTS solo pregunta si hay al menos una fila que cumpla la condición, así que no se ve afectado por NULL ni por pedidos repetidos.
Error común
Así no
SELECT c.id
FROM customers AS c
WHERE c.id NOT IN (SELECT o.customer_id FROM orders AS o);Usar NOT IN con una subconsulta cuya columna admite NULL. Si la subconsulta devuelve un solo NULL, la comparación da «desconocido» para todas las filas y el resultado queda vacío. Aquí funciona porque orders.customer_id es NOT NULL, pero en una columna opcional (un repartidor asignado, un cupón) falla sin avisar.