English

Manual de campo · trampas de SQL

Un WHERE sobre la tabla derecha convierte tu LEFT JOIN en INNER

El ON dice cómo se pegan las filas; el WHERE decide cuáles sobreviven. Con INNER JOIN da igual el orden; con LEFT JOIN, filtrar en el WHERE sobre una columna de la tabla de la derecha borra justo las filas sin pareja que el LEFT JOIN pretendía conservar.

Cuándo aparece

Cada vez que un LEFT JOIN va seguido de un WHERE que menciona una columna de la tabla añadida. Es fácil de escribir y el motor no avisa: simplemente devuelve menos filas de las que pediste.

Ejemplo

Mal: el WHERE descarta los pedidos sin envío

SELECT p.id, e.transportista
FROM pedidos p
LEFT JOIN envios e ON e.pedido_id = p.id
WHERE e.transportista = 'DHL';
-- los pedidos sin envío tienen e.transportista NULL,
-- y NULL = 'DHL' da NULL: la fila se descarta como si fuera INNER JOIN

Bien: la condición vive en el ON, no en el WHERE

SELECT p.id, e.transportista
FROM pedidos p
LEFT JOIN envios e ON e.pedido_id = p.id
                  AND e.transportista = 'DHL';
-- o, si de verdad quieres excluir el resto:
WHERE e.transportista = 'DHL' OR e.transportista IS NULL

Cualquier comparación con NULL da NULL, y una fila cuyo WHERE evalúa a NULL no se devuelve — no es un caso raro, es la regla. Cuando la condición pertenece al criterio de emparejamiento («sólo los envíos de DHL, pero conserva igual los pedidos sin envío»), va en el ON. Cuando de verdad quieres excluir filas del resultado final, entonces sí en el WHERE, añadiendo el OR columna IS NULL para no perder las que no tenían pareja.

Esta trampa —y otras cuatro más— están escondidas en un caso de verdad, con datos de verdad.

Jugar el caso 1 gratis →

Otras trampas