En el artículo anterior aprendimos a relacionar entre sí tablas a través de un campo que implicaba una relación lógica. De este modo, aquellos registros de la primera tabla que no tenían correspondencia con un registro de la segunda eran, automáticamente, omitidos.
En la mayor parte de los casos esto será lo que necesitemos. Sin embargo, no siempre es así. Hay ocasiones en que necesitamos obtener TODOS los registros de una tabla que cumplan determinada condición, tengan o no correspondencia con algún registro de otra tabla. De esto nos vamos a ocupar en este artículo sobre uniones “externas” (OUTER JOIN
).
UNIONES POR LA IZQUIERDA
Tenemos dos tablas, con la misma estructura y datos que en el ejercicio anterior. Para facilitarte la visualización, te reproduzco aquí la estructura de ambas tablas. Sin embargo, para familiarizarnos con la idea de “tabla a la izquierda” y “tabla a la derecha” de la consulta, las hemos puesto una al lado de la otra:
Cómo ves, es la misma estructura que antes, sólo que dispuesta con otra lógica, para facilitarte que te familiarices con esto.
Lo que vamos a hacer es obtener los usuarios que tengan asignada la categoría premium, con independencia de que tengan o no asignada una provincia de residencia. Los que la tengan, aparecerán con su respectiva provincia. Los que no la tengan, tendrán, como provincia, el valor NULL
. La consulta es la siguiente:
1 2 3 4 5 |
SELECT login, provincia FROM usuarios LEFT OUTER JOIN provincias ON provincias.id = id_provincia WHERE premium = 'S'; |
En MySQL podemos expresar esta consulta como LEFT JOIN
o LEFT OUTER JOIN
, indistintamente. En ambos casos, es la misma cláusula y funciona igual.
UNIONES POR LA DERECHA
Este tipo de uniones, aunque conceptualmente son muy similares a las anteriores, son a menudo más complejas de entender e implementar, porque pueden producir resultados inesperados, si la claúsula WHERE de la consulta se centra en la tabla de la izquierda. El objetivo de estas uniones, cómo ya habrás intuido, es recuperar todos los datos de la tabla derecha, tengan o no correspondencia con los de la izquierda. Suponte la siguiente consulta:
1 2 3 4 |
SELECT login, provincia FROM usuarios RIGTH OUTER JOIN provincias ON provincias.id = id_provincia; |
Con esta se recuperarán todas las provincias, con un elemento por cada usuario que la tenga asignada. Los usuarios que no tengan provincia asignada no aparecerán en la lista. Las provincias que no tengan ningún usuario asignado aparecerán con el campo relativo al usuario con el valor NULL. Sin embargo, ten en cuenta que, aunque usemos una RIGTH JOIN
, la cláusual WHERE
de la consulta (si la hubiera), se podría referir a la tabla izquierda (que es lo lógico) y, en ese caso, “manda” sobre la cláusula RIGHT JOIN
. Para que lo entiendas. Supongamos que, en la consulta anterior, hubiéramos filtrado los usuarios premium, como hicimos antes. La consulta quedaría así:
1 2 3 4 5 |
SELECT login, provincia FROM usuarios RIGTH OUTER JOIN provincias ON provincias.id = id_provincia WHERE premium = 'S'; |
Si la pruebas, verás que el resultado coincide con el de INNER JOIN
que vimos en el artículo anterior. Esto es porque no hay provincias que no tengan usuario premium asignado si no tienen ningún usuario asignado (cómo es, en la tabla de ejemplo, la provincia LUGO). Aquí quien “manda” es la cláusula WHERE
aplicada sobre la tabla izquierda.
Al principio cuesta un poco familiarizarse con estas limitaciones, por lo que te recomiendo cambiar valores de las tablas, y probar los scripts adjuntos, para que llegues a interiorizar esta jerarquía de cláusulas.
PRODUCTO CARTESIANO DE DOS TABLAS
En este apartado vamos a ver un tipo específico de unión que, seguramente, llegues a emplear muy pocas veces en tu trabajo, si es que la empleas alguna vez. Se trata de CROSS JOIN
, que podríamos traducir por unión cruzada. Este tipo de unión no emplea cláusula ON
y su objetivo es proporcionar el producto cartesiano de dos tablas, es decir, cada registro de la tabla izquierda aparecerá relacionado con todos y cada uno de los registros de la tabla derecha. La hemos añadido a modo de curiosidad, ya que esto, salvo en pruebas muy específicas, difícilmente nos aportará un resultado relevante. Un ejemplo de esta consulta podría ser el siguiente:
1 2 3 |
SELECT login, provincia FROM usuarios CROSS JOIN provincias; |
CONCLUSIÓN
En este artículo hemos ampliado la posibilidad de selecciones de registros en MySQL. Recuerda que las consultas externas se pueden escribir, indistintamente, con o sin la palabra OUTER
. Es decir, LEFT OUTER JOIN
es equivalente a LEFT JOIN
y RIGHT OUTER JOIN
es equivalente a RIGHT JOIN
. Otras versiones de SQL son más estrictas con este punto, pero MySQL nos permite escribirlas de ambas formas. La base de datos y un script con pruebas de las consultas los encontrarás en este enlace.