Olvida los diagramas de Venn. Un JOIN empareja filas y las pega una al lado de la otra. Solo hay una pregunta que separa los tipos de JOIN: ¿qué ocurre con una fila de la izquierda que no tiene pareja? INNER la descarta. LEFT la conserva y rellena el otro lado con NULL.
🎙️ Publicado y grabado:
-- users -- orders
-- id | name -- id | user_id | amount
-- 1 | Ada -- 1 | 1 | 19.99
-- 2 | Lin -- 2 | 1 | 5.00
-- 3 | Sam -- 3 | 2 | 42.50
-- (Sam no tiene pedidos: fíjate en lo que le ocurre)
SELECT users.name, orders.amount
FROM orders
JOIN users ON orders.user_id = users.id;
-- Ada | 19.99
-- Ada | 5.00 ← Ada coincide dos veces → aparece dos veces
-- Lin | 42.50
-- (Sam no aparece. Sin coincidencia no hay fila. Eso es INNER.)
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON orders.user_id = users.id;
-- Ada | 19.99
-- Ada | 5.00
-- Lin | 42.50
-- Sam | NULL ← se conserva; el lado derecho se rellena con NULL
¿Qué tabla es la «izquierda»? La que aparece después de FROM. «Todos los usuarios y sus pedidos» → users a la izquierda. «Todos los pedidos y su usuario» → orders a la izquierda. Di la frase en voz alta: la frase elige la tabla.
-- "usuarios que nunca han hecho un pedido"
SELECT users.name
FROM users
LEFT JOIN orders ON orders.user_id = users.id
WHERE orders.id IS NULL; -- la ausencia de coincidencia ES el filtro
-- → Sam
WHERE orders.amount > 10— y las filas con NULL desaparecen: NULL > 10 no es verdadero, así que Sam queda fuera y el LEFT JOIN se comporta como INNER sin avisar. Solución: coloca las condiciones de la tabla derecha en la cláusula ON —ON orders.user_id = users.id AND orders.amount > 10— para filtrar las coincidencias sin perder las filas que no tienen pareja.
SELECT u.name, o.amount, p.title
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;
-- cada JOIN añade otra tabla a una fila que se va ensanchando.
-- los alias cortos (o, u, p) mantienen la consulta legible.
RIGHT JOIN -- es un LEFT JOIN con las tablas intercambiadas. casi nadie
-- lo escribe; pásalo a LEFT y conserva un único modelo mental.
FULL JOIN -- conserva las filas sin pareja de AMBOS lados. raro; auditorías.
CROSS JOIN -- todas las combinaciones (sin ON). tallas × colores = variantes.