Consultas en más de una tabla III – OUTER JOIN

Categories:

Después de revisar consultas anidadas y algunas variantes de JOIN llegamos a LEFT / RIGHT – OUTER – JOIN.

LEFT / RIGHT – OUTER – JOIN

Este tipo de JOIN funciona de manera similar a los JOINS que vimos en la entrada anterior. Se asocian los registros de las tablas seleccionadas utilizando las columnas designadas – llave primaria, llave foránea generalmente -. La diferencia radica en que en estas consultas también se muestran los registros de una tabla que no tienen registros asociados en otra tabla.

Comenzamos con el ejemplo de la entrada anterior:

SELECT niveles.nombre, publicaciones.titulo 
FROM niveles JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id;

JOIN

¿Cómo podemos especificar de qué tabla se van mostrar los registros que no están asociados?

En particular ¿cómo podemos especificar que queremos mostrar los niveles que no tienen una publicación asociada? o ¿cómo podemos mostrar las publicaciones que no tienen un nivel asociado?

La manera que tenemos para especificar la tabla “principal” es indicarlo directamente en la consulta – para eso se utiliza LEFT o RIGHT -.

En el caso de LEFT JOIN la tabla de la “izquierda” – la que aparece antes de LEFT JOIN – es la que se considera principal.
En el caso de RIGHT JOIN, la tabla principal es la que está después de RIGHT JOIN.

Regresando al ejemplo, en este caso queremos mostrar los todos niveles y la publicación que cada uno de ellos está clasificando. Queremos incluir los niveles que no están clasificando ninguna publicación.

SELECT niveles.nombre, publicaciones.titulo 
FROM  niveles LEFT OUTER JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id;

LEFT OUTER JOIN

Al no mostrarse registros con el nombre del nivel asignado y el título de la publicación con el valor NULL quiere decir que todos los niveles están asociados a una publicación.

En el caso de querer mostrar todas las publicaciones con el nivel con el que están clasificadas – incluyendo aquellas que no tienen asignado un nivel – podemos cambiar el orden de las tablas en LEFT OUTER JOIN o podemos utilizar RIGHT OUTER JOIN y dejar las tablas en el orden que tenían.

En este caso voy a utilizar RIGHT OUTER JOIN.

SELECT niveles.nombre, publicaciones.titulo 
FROM  niveles RIGHT OUTER JOIN publicaciones
ON niveles.id = publicaciones.nivel_id;

RIGHT OUTER JOIN

En este caso hay dos publicaciones – PHP y Servidor Web – que no tienen un nivel asociado.
En el caso de no existir un registro asociado, el valor de las columnas seleccionadas va a ser NULL.

Nota:
En MySQL el término OUTER es opcional.
Las consultas anteriores se pueden escribir así y dan el mismo resultado:

SELECT niveles.nombre, publicaciones.titulo 
FROM  niveles LEFT JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id;


SELECT niveles.nombre, publicaciones.titulo 
FROM  niveles RIGHT JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id;

LEFT JOIN

RIGHT JOIN

Es posible utilizar gran parte de lo que hemos visto – filtrar, ordenar, limitar, funciones, alias -.

SELECT niveles.nombre, publicaciones.titulo
FROM  niveles RIGHT JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id 
WHERE publicaciones.titulo LIKE  "%css%";

SELECT niveles.nombre, publicaciones.titulo
FROM  niveles RIGHT JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id 
WHERE publicaciones.titulo NOT LIKE  "%css%";

SELECT niveles.nombre AS 'nivel', publicaciones.titulo AS 'publicación', publicaciones.votos 
FROM  niveles RIGHT JOIN publicaciones 
ON niveles.id = publicaciones.nivel_id
WHERE votos > 0
ORDER BY votos DESC
LIMIT 5;

FILTRAR LEFT JOIN

FILTRAR RIGHT JOIN

Unir, filtrar, ordenar, limitar

Nota:
Aunque no es necesario utilizar la sintaxis {tabla}.{columna} cuando las columnas tienen diferente nombre en las tablas es mejor acostumbrarse a utilizar esta sintaxis. De esta manera prevenimos un error en el caso de que el nombre de la columna se repita en las tablas seleccionadas.

En caso de que el nombre de las tablas sea muy largo o queramos seleccionar varias columnas de una tabla podemos utilizar un alias de tabla para abreviar el nombre.