En la lección anterior aprendimos como insertar registros en una tabla y consultarlos. Sin embargo, cuando trabajas con bases de datos, lo más común es obtener información de varias tablas relacionadas entre sí. Una de las maneras más eficientes de lograr esto es a través del operador JOIN
.
Pero antes de conocer este operador, veamos los datos de nuestra base de datos:
Sucusales:
MariaDB [storage]> SELECT id, name, start_date FROM branches; +----+------------+------------+ | id | name | start_date | +----+------------+------------+ | 1 | SUCURSAL A | 2020-07-16 | | 2 | SUCURSAL B | 2020-08-16 | | 3 | SUCURSAL C | 2020-09-16 | | 4 | SUCURSAL D | 2020-10-16 | +----+------------+------------+ 4 rows in set (0.000 sec)
Empleados:
MariaDB [storage]> SELECT id, branch_id, dni, first_name, last_name, birth_date FROM employees; +----+-----------+----------+------------+-----------+------------+ | id | branch_id | dni | first_name | last_name | birth_date | +----+-----------+----------+------------+-----------+------------+ | 1 | NULL | 15024001 | Harry | Smith | 2000-01-01 | | 2 | 1 | 15024002 | Jacob | Johnson | 2000-01-02 | | 3 | 2 | 15024003 | Ryan | Gold | 2020-01-03 | | 4 | NULL | 15024004 | Liam | Evans | 2020-01-04 | | 5 | 1 | 15024005 | Charlie | Adams | 2020-01-05 | | 6 | 2 | 15024006 | Amelia | Miller | 2020-01-06 | | 7 | 1 | 15024007 | Mia | Owen | 2020-01-07 | | 8 | NULL | 15024008 | Aurora | Graham | 2020-01-08 | | 9 | 3 | 15024009 | Isabella | Stone | 2020-01-09 | | 10 | 1 | 15024010 | Elizabeth | Bennett | 2020-01-10 | +----+-----------+----------+------------+-----------+------------+ 10 rows in set (0.001 sec)
Operador JOIN
La operador JOIN
nos permite enlazar dos tablas por medio de un campo en común, el cual puede ser un campo clave o no.
Como resultado, obtendremos todos los registros de ambas tablas donde el campo en común tengan el mismo valor. Veamos esto con un ejemplo.
Supongamos que queremos obtener todos los empleados que están asignados a una sucursal:
MariaDB [storage]> SELECT E.id, E.dni, E.first_name, E.last_name, E.branch_id, B.name AS branch FROM employees AS E JOIN branches AS B ON E.branch_id = B.id;
La cláusula AS
nos permite asignar un «apodo» a los nombres de campos y tablas. Esto resulta muy útil para colocar un nombre alternativo a campos/tablas o evitar conflictos con nombres de campos repetidos.
El operador JOIN
se puede usar con el comando SELECT
después de la cláusula FROM
. Va seguido del nombre de la tabla que se desea «enlazar», luego la cláusula ON
, y por último se comparan los campos en común.
En otras palabras, la tabla employees
se enlaza con la tabla branches
por medio de los campos branch_id
e id
.
Los nombres de campos utilizados en las cláusulas JOIN
y WHERE
no pueden ser los «apodos» asignados con la cláusula AS
.
La consulta anterior nos devolverá un resultado como el siguiente:
+----+----------+------------+-----------+-----------+------------+ | id | dni | first_name | last_name | branch_id | branch | +----+----------+------------+-----------+-----------+------------+ | 2 | 15024002 | Jacob | Johnson | 1 | SUCURSAL A | | 3 | 15024003 | Ryan | Gold | 2 | SUCURSAL B | | 5 | 15024005 | Charlie | Adams | 1 | SUCURSAL A | | 6 | 15024006 | Amelia | Miller | 2 | SUCURSAL B | | 7 | 15024007 | Mia | Owen | 1 | SUCURSAL A | | 9 | 15024009 | Isabella | Stone | 3 | SUCURSAL C | | 10 | 15024010 | Elizabeth | Bennett | 1 | SUCURSAL A | +----+----------+------------+-----------+-----------+------------+ 7 rows in set (0.001 sec)
El alias en la consulta colocó el apodo branch
al campo name
de la tabla branches
Recuerda que los datos pueden variar dependiendo de los empleados/sucursales que tengas registrados.
Nota que en la consulta hemos especificado tanto los campos, como el orden en que deseamos mostrarlos, pero ¿qué pasa si usamos el comodín (*
)?
Al usar el comodín, se mostrarán todos los campos de la tabla izquierda y luego todos los campos de la tabla derecha.
La tabla izquierda (lado izquierdo) es la que se define antes del operador JOIN
y la tabla derecha (lado derecho) es la que se define después del mismo.
Por ejemplo, si ejecutamos la siguiente consulta:
MariaDB [storage]> SELECT * FROM employees AS E JOIN branches AS B ON E.branch_id = B.id;
La lista de campos de nuestro resultado estará ordenada con todos los campos de la tabla employees
primero y luego con todos los campos de la tabla branches
.
Recuerda, te recomendamos siempre especificar el nombre de tus campos al construir consultas.
Cláusula LEFT JOIN
Al igual que el operador JOIN
, la cláusula LEFT JOIN
nos permite enlazar dos tablas, pero el resultado de la consulta incluirá todos los registros del lado izquierdo.
En otras palabras, la cláusula LEFT JOIN
retornará todos los registros del lado izquierdo (aunque el campo en común no tenga coincidencias), y todos los registros del lado derecho donde coincida el campo en común.
Veamos un ejemplo. Vamos a repetir nuestra consulta inicial usando la cláusula LEFT JOIN
MariaDB [storage]> SELECT E.id, E.dni, E.first_name, E.last_name, E.branch_id, B.name AS branch FROM employees AS E LEFT JOIN branches AS B ON E.branch_id = B.id;
Esto nos devolverá el siguiente resultado:
+----+----------+------------+-----------+-----------+------------+ | id | dni | first_name | last_name | branch_id | branch | +----+----------+------------+-----------+-----------+------------+ | 1 | 15024001 | Harry | Smith | NULL | NULL | | 2 | 15024002 | Jacob | Johnson | 1 | SUCURSAL A | | 3 | 15024003 | Ryan | Gold | 2 | SUCURSAL B | | 4 | 15024004 | Liam | Evans | NULL | NULL | | 5 | 15024005 | Charlie | Adams | 1 | SUCURSAL A | | 6 | 15024006 | Amelia | Miller | 2 | SUCURSAL B | | 7 | 15024007 | Mia | Owen | 1 | SUCURSAL A | | 8 | 15024008 | Aurora | Graham | NULL | NULL | | 9 | 15024009 | Isabella | Stone | 3 | SUCURSAL C | | 10 | 15024010 | Elizabeth | Bennett | 1 | SUCURSAL A | +----+----------+------------+-----------+-----------+------------+ 10 rows in set (0.001 sec)
Nota que ahora obtenemos todos los empleados, aunque no tengan sucursales asignadas. Además, dado que el campo en común tiene el valor NULL
en el lado izquierdo, se completa con valores NULL
los campos del lado derecho.
Esta cláusula resulta bastante útil cuando deseamos agregar a nuestros resultados los registros del lado izquierdo que no tienen coincidencias en el lado derecho. Vamos a verlo con un ejemplo.
Supongamos que nos solicitan un reporte con los empleados que no están asignados a una sucursal, pero además, este reporte debe incluir los empleados que pertenecen a sucursales cuya fecha de apertura sea desde el 01 de septiembre de 2020.
Podemos lograr esto ejecutando la siguiente consulta:
MariaDB [storage]> SELECT E.id, E.dni, E.first_name, E.last_name, E.branch_id, B.name AS branch, B.start_date FROM employees AS E LEFT JOIN branches AS B ON E.branch_id = B.id WHERE E.branch_id IS NULL OR B.start_date >= '2020-09-01';
Hemos incluido las cláusulas WHERE
y OR
para filtrar nuestros resultados por los empleados que no tienen sucursal (E.branch_id IS NULL
) o (OR
) cuya sucursal tiene fecha de apertura mayor o igual al 01 de Septiembre del 2020 (B.start_date >= '2020-09-01'
).
La cual nos mostrará el siguiente resultado:
+----+----------+------------+-----------+-----------+------------+-----------+ | id | dni | first_name | last_name | branch_id | branch | start_date| +----+----------+------------+-----------+-----------+------------+-----------+ | 1 | 15024001 | Harry | Smith | NULL | NULL | NULL | | 4 | 15024004 | Liam | Evans | NULL | NULL | NULL | | 8 | 15024008 | Aurora | Graham | NULL | NULL | NULL | | 9 | 15024009 | Isabella | Stone | 3 | SUCURSAL C | 2020-09-16| +----+----------+------------+-----------+-----------+------------+-----------+ 4 rows in set (0.000 sec)
Cláusula RIGHT JOIN
La cláusula RIGHT JOIN
es similar a la cláusula LEFT JOIN
, pues también nos permite enlazar dos tablas, pero el resultado de la consulta incluirá todos los registros del lado derecho.
Es decir, la cláusula RIGHT JOIN
retornará todos los registros del lado derecho (aunque el campo en común no tenga coincidencias), y todos los registros del lado izquierdo donde coincida el campo en común.
Veamos un ejemplo. Vamos a repetir nuestra consulta inicial usando la cláusula RIGHT JOIN
:
MariaDB [storage]> SELECT E.id, E.dni, E.first_name, E.last_name, E.branch_id, B.name AS branch FROM employees AS E RIGHT JOIN branches AS B ON E.branch_id = B.id;
Esto nos devolverá el siguiente resultado:
+------+----------+------------+-----------+-----------+------------+ | id | dni | first_name | last_name | branch_id | branch | +------+----------+------------+-----------+-----------+------------+ | 2 | 15024002 | Jacob | Johnson | 1 | SUCURSAL A | | 5 | 15024005 | Charlie | Adams | 1 | SUCURSAL A | | 7 | 15024007 | Mia | Owen | 1 | SUCURSAL A | | 10 | 15024010 | Elizabeth | Bennett | 1 | SUCURSAL A | | 3 | 15024003 | Ryan | Gold | 2 | SUCURSAL B | | 6 | 15024006 | Amelia | Miller | 2 | SUCURSAL B | | 9 | 15024009 | Isabella | Stone | 3 | SUCURSAL C | | NULL | NULL | NULL | NULL | NULL | SUCURSAL D | +------+----------+------------+-----------+-----------+------------+ 8 rows in set (0.001 sec)
Nota que ahora obtenemos todas las sucursales aunque no tengan empleados, y así como con la cláusula LEFT JOIN
, se completa con valores NULL
los campos del lado izquierdo donde no hay coincidencias.
Veamos la utilidad de esta cláusula con el siguiente ejemplo. Supongamos que deseamos obtener todas las sucursales que no tienen empleados.
Podemos lograr esto con la siguiente consulta:
MariaDB [storage]> SELECT B.id, B.name AS branch, B.start_date FROM employees AS E RIGHT JOIN branches AS B ON E.branch_id = B.id WHERE E.id IS NULL;
La cual nos devolverá el siguiente resultado:
+----+------------+------------+ | id | branch | start_date | +----+------------+------------+ | 4 | SUCURSAL D | 2020-10-16 | +----+------------+------------+ 1 row in set (0.001 sec)
Puedes aprender mucho más sobre cómo construir consultas con estas cláusulas leyendo nuestro libro Aprende SQL con MySQL y MariaDB.
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Insertar y Consultar datos en MySQL / MariaDB Lección siguiente Actualizar y Eliminar datos en MySQL / MariaDB