2.5.6. Consultas de mas de una tabla

2.5.6. Consultas de mas de una tabla Dataprix 21 September, 2009 - 11:17

Muchas veces queremos consultar datos de más de una tabla haciendo combinaciones de columnas de tablas diferentes. En el SQL es posible listar más de una tabla que se quiere consultar especificándolo en la cláusula FROM.

1)  Combinación

Recordad que la misma operación de combinación, pero del álgebra relacional, se ha visto en el subapartado 5.3.3. de la unidad "El modelo relacional y el álgebra relacional"

La combinación consigue crear una sola tabla a partir de las tablas especificadas en la cláusula FROM, haciendo coincidir los valores de las columnas relacionadas de estas tablas.

Ejemplo de combinación en BDUOC

A continuación mostramos un ejemplo con la base de datos BDUOC en el que queremos saber el NIF del cliente y el código y el precio del proyecto que desarrollamos para el cliente número 20:

SELECT proyectos.codigo_proyecto, proyectos.precio, clientes.nif
FROM clientes, proyectos
WHERE clientes.codigo_cli = proyectos.codigo_cliente AND clientes.
codigo_cli = 20;

 El resultado sería:

proyectos.codigo_proyecto proyectos.precio clientes.nif
3 1.000.000 38.123.898-E

 

Si trabajamos con más de una tabla, puede ocurrir que la tabla resultante tenga dos columnas con el mismo nombre. Por ello es obligatorio especificar a qué tabla corresponden las columnas a las que nos estamos refiriendo, denominando la tabla a la que pertenecen antes de ponerlas (por ejemplo, clientes.codigo_cli). Para simplificarlo, se utilizan los alias que, en este caso, se definen en la cláusula FROM.

 

Ejemplo de alias en BDUOC

c podría ser el alias de la tabla clientes. De este modo, para indicar a qué tabla pertenece codigo_cli, sólo haría falta poner: c.codigo_cli.

Veamos cómo quedaría la consulta anterior expresada mediante alias, aunque en este ejemplo no serían necesarios, porque todas las columnas de las dos tablas tienen nombres diferentes. Pediremos, además, las columnas c.codigo_cli y p.codigo_cliente.

SELECT p.codigo_proyecto, p.precio, c.nif, p.codigo_cliente, c.codigo_cli
FROM clientes c, proyectos p
WHERE c.codigo_cli = p.codigo_cliente AND c.codigo_cli = 20;

 

Entonces obtendríamos este resultado:

p.codigo_proyec p.precio c.nif p.codigo_cliente c.codigo_cli
3 1.000.000 38.123.898-E 20 20

Notemos que en WHERE necesitamos expresar el vínculo que se establece entre las dos tablas, en este caso codigo_cli de clientes y codigo_cliente de proyectos. Expresado en operaciones del álgebra relacional, esto significa que hacemos una combinación en lugar de un producto cartesiano.

Las operaciones del álgebra relacional se han visto en el apartado 5 de la unidad "El modelo relacional y el álgebra relacional"

Fijémonos en que, al igual que en álgebra relacional, la operación que acabamos de hacer es una equicombinación (equi-join); por lo tanto, nos aparecen dos columnas idénticas: c.codigo_cli y p.codigo_cliente.

 

La forma de expresar la combinación que acabamos de ver pertenece al SQL92 introductorio. Una forma alternativa de realizar la equicombinación anterior, utilizando el SQL92 intermedio o completo, sería la siguiente:

SELECT nombre_columnas_a_seleccionar
FROM tabla1 JOIN tabla2
     {ON condiciones|USING (columna [, columna...])}
[WHERE condiciones];

 

Ejemplo anterior con el SQL92 intermedio o completo

El ejemplo que hemos expuesto antes utilizando el SQL92 intermedio o completo sería:

SELECT p.codigo_proyecto, p.precio, c.nif, p.codigo_cliente, c.codigo_cli
FROM clientes c JOIN proyectos p ON c.codigo_cli = p.codigo_cliente
WHERE c.codigo_cli = 20;

Y obtendríamos el mismo resultado de antes.

 

Pdemos ver la equicombinación y la Ø-combinación en el subapartado 5.3.3. de la unidad "El modelo relacional y el álgebra relacional"

La opción ON, además de expresar condiciones con la igualdad, en el caso de que las columnas que queramos vincular tengan nombres diferentes, nos ofrece la posibilidad de expresar condiciones con los demás operadores de comparación que no sean el de igualdad. Sería el equivalente a la operación que en álgebra relacional hemos denominado Ø-combinación (Ø-join).

 

También  podemos  utilizar  una  misma  tabla  dos  veces  con  alias  diferentes, para distinguirlas.

Dos alias para una misma tabla en BDUOC

Si pidiésemos los códigos y los apellidos de los empleados que ganan más que el empleado que tiene por código el número 5, haríamos lo siguiente:

SELECT p.codigo_proyecto, p.precio, c.nif, p.codigo_cliente, c.codigo_cli
FROM clientes c JOIN proyectos p ON c.codigo_cli = p.codigo_cliente
WHERE c.codigo_cli = 20;

 

Hemos tomado la tabla e2 para fijar la fila del empleado con código número 5, de modo que
podamos comparar el sueldo de la tabla e1, que contiene a todos los empleados, con el sueldo de la tabla e2, que contiene sólo al empleado 5.

La respuesta a esta consulta sería:

e1.codigo_empl e1.apellido_empl
1 Puig
2 Mas
3 Ros
4 Roca

 

2)  Combinación natural

La  combinación  natural  (natural  join)  de  dos  tablas  consiste  básicamente,  al igual que en el álgebra relacional, en hacer una equicombinación entre columnas del mismo nombre y eliminar las columnas repetidas. La combinación natural, utilizando el SQL92 intermedio o completo, se haría de la forma siguiente:

SELECT nombre_columnas_a_seleccionar
FROM tabla1 NATURAL JOIN tabla2
[WHERE condiciones];

 

Combinación natural en BDUOC

Veamos a continuación un ejemplo en el que las columnas para las que se haría la combinación natural se denominan igual en las dos tablas. Ahora queremos saber el código y el nombre de los empleados que están asignados al departamento cuyo teléfono es 977.33.38.52:

SELECT codigo_empl, nombre_empl
FROM empleados NATURAL JOIN departamentos
WHERE telefono = '977.333.852';

La combinación natural también se podría hacer con la cláusula USING, sólo aplicando la palabra reservada JOIN: 

SELECT codigo_empl, nombre_empl
FROM empleados JOIN departamentos USING (nombre_dep, ciudad_dep)
WHERE telefono = '977.333.852';

La respuesta que daría sería:

empleados.codigo_empl empleados.nombre_empl
5 Clara
6 Laura
8 Sergio

 

 
3)  Combinación interna y externa

Cualquier combinación puede ser interna o externa:

a)  La combinación interna (inner join) sólo se queda con las filas que tienen valores idénticos en las columnas de las tablas que compara. Esto puede hacer que perdamos alguna fila interesante de alguna de las dos tablas; por ejemplo, porque se encuentra a NULL en el momento de hacer la combinación. Su formato es el siguiente:

SELECT nombre_columnas_a_seleccionar
FROM t1 [NATURAL] [INNER] JOIN t2
       {ON condiciones|
       |USING(columna [,columna...])}
[WHERE condiciones];

 

b)  Por ello disponemos de la combinación externa (outer join), que nos permite obtener todos los valores de la tabla que hemos puesto a la derecha, los de la tabla que hemos puesto a la izquierda o todos los valores de las dos tablas. Su formato es:

SELECT nombre_columnas_a_seleccionar
FROM t1 [NATURAL] [LEFT|RIGHT|FULL] [OUTER] JOIN t2
       {ON condiciones|
       [USING (columna [,columna...])}
[WHERE condiciones];

 

Combinación natural interna en BDUOC

Combinación interna
Aunque en el ejemplo estamos haciendo una combinación natural interna, no es necesario poner la palabra INNER, ya que es la opción por defecto.

Si quisiéramos vincular con una combinación natural interna las tablas empleados y
departamentos para saber el código y el nombre de todos los empleados y el nombre, la ciudad y el teléfono de todos los departamentos, haríamos:

SELECT e.codigo_empl, e.nombre_empl, e.nombre_dep, e.ciudad_dep, d.telefono
FROM empleados e NATURAL JOIN departamentos d;

 Y obtendríamos el siguiente resultado:

e.codigo_empl e.nombre_empl e.nombre_dep e.ciudad_dep d.teléfono
1 María DIR Girona 972.23.89.70
2 Pedro DIR Barcelona 93.422.60.70
3 Ana DIS Lleida 973.23.50.40
4 Jorge DIS Barcelona 93.224.85.23
5 Clara PROG Tarragona 977.33.38.52
6 Laura PROG Tarragona 977.33.38.52
8 Sergio PROG Tarragona 977.33.38.52

 

 Fijémonos en que en el resultado no aparece el empleado número 7, que no está asignado a ningún departamento, ni el departamento de programación de Girona, que no tiene ningún empleado asignado.

Combinación natural externa a BDUOC

En los ejemplos siguientes veremos cómo varían los resultados que iremos obteniendo según los tipos de combinación externa:

a) Combinación externa izquierda

SELECT e.codigo_empl, e.nombre_empl, e.nombre_dep, e.ciudad_dep, d.telefono
FROM empleados e NATURAL LEFT OUTER JOIN departamentos d;
Combinación externa izquierda
Aquí fighura el empleado 7.

 El resultado sería el que podemos ver a continuación:

e.codigo_empl e.nombre_emple e.nombre_dep e.ciudad_dep d.telefono
 1  María DIR  Girona 972.23.89.70
 2  Pedro  DIR  Barcelona  93.422.60.70
 3  Ana  DIS  Lleida 973.23.50.40
 4  Jorge  DIS  Barcelona  93.224.85.23
 5  Clara  PROG  Tarragona  977.33.38.52
 6  Laura  PROG Tarragona  977.33.38.52
 7  Rogelio  NULL  NULL  NULL
 8 Sergio  PROG Tarragona  977.33.38.52

b) Combinación externa derecha

SELECT e.codigo_empl, e.nombre_empl, e.nombre_dep, e.ciudad_dep, d.telefono
FROM empleados e NATURAL RIGHT OUTER JOIN departamentos d;

 

Combinación externa derecha

Aquí figura el departamento de programación d

Obtendríamos este resultado:

e.codigo_empl e.nombre_emple e.nombre_dep e.ciudad_dep d.telefono
 1  María DIR  Girona 972.23.89.70
 2  Pedro  DIR  Barcelona  93.422.60.70
 3  Ana  DIS  Lleida 973.23.50.40
 4  Jorge  DIS  Barcelona  93.224.85.23
 5  Clara  PROG  Tarragona  977.33.38.52
 6  Laura  PROG Tarragona  977.33.38.52
 8 Sergio  PROG Tarragona  977.33.38.52
 NULL  NULL PROG  Girona 9272.23.50.91

c) Combinación externa plena

SELECT e.codigo_empl, e.nombre_empl, e.nombre_dep, e.ciudad_dep, d.telefono
FROM empleados e NATURAL FULL OUTER JOIN departamentos d;
Combinación externa plena
Aquí figura el empleado 7 y el departamento de programación de Girona.

Y obtendríamos el siguiente resultado:

e.codigo_empl e.nombre_emple e.nombre_dep e.ciudad_dep d.telefono
 4  Jorge  DIS  Barcelona  93.224.85.23
 5  Clara  PROG  Tarragona  977.33.38.52
 6  Laura  PROG Tarragona  977.33.38.52
 7  Rogelio  NULL  NULL  NULL
 8 Sergio  PROG Tarragona  977.33.38.52
 NULL  NULL PROG  Girona 9272.23.50.91

 

4)  Combinaciones con más de dos tablas

Si queremos combinar tres tablas o más con el SQL92 introductorio, sólo tenemos que añadir todas las tablas en el FROM y los vínculos necesarios en el WHERE. Si queremos combinarlas con el SQL92 intermedio o con el completo, tenemos que ir haciendo combinaciones de tablas por pares, y la tabla resultante se convertirá en el primer componente del siguiente par. 

Combinaciones con más de dos tablas en BDUOC

Veamos ejemplos de los dos casos, suponiendo que queremos combinar las tablas empleados, proyectos y clientes:

SELECT *
FROM empleados, proyectos, clientes
WHERE num_proyec = codigo_proyec AND codigo_cliente = codigo_cli;

o bien:

SELECT *
FROM (empleados JOIN proyectos ON num_proyec = codigo_proyec)
JOIN clientes ON codigo_cliente = codigo_cli;