T06 Consultas Sobre Varias Tablas
T06 Consultas Sobre Varias Tablas
T06 Consultas Sobre Varias Tablas
Sumario
6.1. Consultas multitabla SQL-1..........................................................................................................1
6.1.1. Composición cruzada (producto cartesiano)..........................................................................1
6.1.2. Composiciones internas.........................................................................................................3
6.2. Consultas SQL-2...........................................................................................................................6
6.2.1. Composiciones cruzadas........................................................................................................6
6.2.2. Composiciones internas.........................................................................................................6
6.2.3. Composiciones externas........................................................................................................7
6.3. Unir tres o más tablas./..................................................................................................................9
6.4. Unir una tabla consigo misma. (self-equi-join).............................................................................9
6.5. Ejercicios.....................................................................................................................................10
6.5.1. Base de datos: Tienda informática.......................................................................................10
6.5.2. Base de datos: Gestión de empleados..................................................................................11
6.5.3. Base de datos: Gestión de ventas.........................................................................................12
Las consultas multitabla nos permiten consultar información en más de una tabla. La única
diferencia respecto a las consultas sencillas es que vamos a tener que especificar en la cláusula
FROM cuales son las tablas que vamos a usar y cómo las vamos a relacionar entre sí.
Para realizar este tipo de consultas podemos usar dos alternativas:
• Sintaxis de SQL 1 (SQL-86), que consiste en realizar el producto cartesiano de las tablas y
añadir un filtro para relacionar los datos que tienen en común.
• Sintaxis de SQL 2 (SQL-92 y SQL-2003) que incluye todas las cláusulas del tipo JOIN.
1
Ejemplo, supongamos las siguientes tablas: empleado y departamento
El producto cartesiano de las dos tablas tendría 84 registros resultantes de combinar cada empleado
con los 6 departamentos recogidos.
Veamos como sería el resultado:
2
Observa que para indicar un atributo de una tabla se pone el nombre de la tabla seguido de un punto
y el nombre del atributo. Esto es necesario solo si hay ambigüedad para distinguir que atributo es.
En el caso del código es obligatorio hacerlo: departamento.codigo y empleado.codigo; pero con nif,
apellido1, apellido2, presupuesto,.. no haría falta pues solo están esos atributos en una de las tablas.
3
Para poder realizar una operación de intersección entre dos tablas debemos utilizar la cláusula
WHERE para indicar la columna con la que queremos relacionarlas.
Ejemplo: obtener un listado de los empleados y el departamento donde trabaja cada uno de ellos
podemos realizar la siguiente consulta.
En la operación de intersección sólo obtendremos los elementos que existan en ambos conjuntos.
Por lo tanto, puede ocurrir que haya filas en la tabla de empleado que no aparezcan en el resultado y
filas de la tabla de departamento que tampoco estén. Serán empleados que no estén asignados a
ningún departamento y departamentos que no tengan asignado a ningún empleado.
Comparando la solución SQL-1 con SQL-2 tendríamos:
SQL-1:
msql>SELECT empleado.nombre, empleado.apellido1, departamento.nombre
FROM empleado, departamento
WHERE empleado.codigo_departamento=departamento.codigo;
SQL-2:
mysql>SELECT empleado.nombre, empleado.apellido1, departamento.nombre
FROM empleado INNER JOIN departamento
ON empleado.codigo_departamento=departamento.codigo;
En ambas soluciones se mostrarán solo los registros relacionados y no aparecerán los empleados
que no pertenezcan a ningún departamento, ni los departamentos sin empleados:
4
No aparecerán en la intersección:
• Las filas de empleado:
◦ Maria Triana
◦ Fernando Fernan
• Las filas de departamento:
◦ Ventas
◦ Contabilidad
Los resultados obtenidos son independientes del orden en el que se pongan las tablas:
mysql>SELECT empleado.nombre, empleado.apellido1, departamento.nombre
FROM empleado INNER JOIN departamento
ON empleado.codigo_departamento=departamento.codigo;
es equivalente a:
mysql>SELECT empleado.nombre, empleado.apellido1, departamento.nombre
FROM departamento INNER JOIN empleado
ON empleado.codigo_departamento=departamento.codigo;
5
6.2. Consultas SQL-2.
6.2.1. Composiciones cruzadas.
La composición cruzada (producto cartesiano) se hace con la cláusula: [CROSS] JOIN. La palabra
CROSS es opcional.
• NATURAL JOIN tabla. En este caso se devuelve la intersección de las dos tablas, pero
utilizando para ello las columnas cuyos nombres coincidan, es por ello que no necesita la
cláusula ON. De nuestro ejemplo, código y nombre son atributos que aparecen en las dos
tablas, mostraría los registros cuyo código de empleado coincida con el código de
departamento y que el nombre de empleado coincida con el nombre de departamento, es
decir, ninguno.
Para usar la cláusula NATURAL, se ha de estar seguro de que las columnas por las que
vamos a realizar la intersección se llaman igual en las dos tablas. Lo normal es que esto no
ocurra, por lo que lo más utilizado es INNER JOIN o JOIN.
6
6.2.3. Composiciones externas.
En las composiciones externas se incluyen todos los registros de la tabla que aparece a la derecha o
a la izquierda, según la opción, de la cláusula JOIN, estén o no relacionados con algún registro de la
otra tabla.
Las distintas composiciones externas son:
• LEFT [OUTER] JOIN.
• RIGHT [OUTER] JOIN.
• FULL [OUTER] JOIN (no implementado en MySQL).
• NATURAL LEFT [OUTER] JOIN.
• NATURAL RIGHT [OUTER] JOIN.
Al usar “empleado LEFT JOIN departamento” mostrará la intersección y todos los registros que
aparecen en la tabla a la izquierda de JOIN: empleado. Se incluye: María Triana y Fernando Fernan,
sin embargo no aparecen los registros de departamentos que no tienen relación: “ni Ventas ni
Contabilidad”.
7
La consulta FULL OUTER JOIN no está implementada en MySQL, pero se podría simular con el
operador UNION, que realizaría la unión de dos consultas que se hagan. Se aplicará a una consulta
LEFT JOIN y otra RIGHT JOIN.
El resultado de FULL JOIN es obtener la intersección de dos tablas y todos los elementos de cada
tabla que no estén en la intersección. En nuestro caso de tabla empleados y departamentos deben
aparecer:
• Registros de la intersección. Es decir, empleados que están asignados a un departamento.
Los datos del empleado y del departamento, que se especifiquen.
• Registros de empleados que no están asignados a ningún departamento. En este caso
aparecerán en NULL los campos del departamento.
• Registros de departamentos que no tienen empleados. Igualmente aparecerán en NULL los
atributos de empleado.
Respecto a las composiciones con NATURAL LEFT JOIN y NATURAL RIGHT JOIN, Hay que
tener en cuenta que la composición se hará sobre columnas que se llamen igual, luego no hace falta
la cláusula ON, igualmente se incluirán en la consulta los registros que no coincidan en la
intersección de la tabla a la izquierda o de la tabla a la derecha, respectivamente.
8
6.3. Unir tres o más tablas./
La unión de más de dos tablas se realiza añadiendo cláusulas JOIN.
Ejemplo:
msql> SELECT * FROM cliente
INNER JOIN empleado ON cliente.codigo_empleado_venta=empleado.codigo
INNER JOIN pago ON cliente.codigo=pago.codigo_cliente;
9
6.5. Ejercicios.
6.5.1. Base de datos: Tienda informática.
La descripción de las tablas utilizadas es:
Multitabla.
1. Devuelve una lista con el nombre del producto, precio y nombre de fabricante de todos los
productos de la base de datos. Ordene el resultado alfabéticamente por nombre de
fabricante.
2. Devuelve el nombre del producto, su precio y el nombre de su fabricante, del producto más
barato.
3. Devuelve el nombre del producto, su precio y el nombre de su fabricante, del producto más
caro.
4. Devuelve una lista de todos los productos del fabricante Crucial y que su precio sea mayor
de 200 euros.
5. Devuelve un listado con todos los productos de los fabricantes Asus, Hewlett-Packard y
Seagate.
6. Devuelve un listado con el nombre y el precio de todos los productos de los fabricantes cuyo
nombre termine por la vocal “e”.
7. Devuelve un listado con el nombre y el precio de todos los productos cuyo nombre de
fabricante contenga el carácter “w” en su nombre.
8. Devuelve un listado con el nombre de producto, precio y nombre de fabricante, de todos los
productos que tengan un precio mayor o igual a 180€. Ordene el resultado en primer lugar
por el precio (en orden descendente) y en segundo lugar por el nombre (en orden
ascendente).
9. Devuelve un listado con el código y el nombre de fabricante, solamente de aquellos
fabricantes que tienen productos asociados en la base de datos.
10
10. Devuelve un listado de todos los fabricantes que existen en la base de datos, junto con los
productos que tiene cada uno de ellos. El listado deberá mostrar también aquellos
fabricantes que no tienen productos asociados.
11. Devuelve un listado donde sólo aparezcan aquellos fabricantes que no tienen ningún
producto asociado.
11
10. Devuelve un listado con el nombre de los departamentos donde existe algún empleado cuyo
segundo apellido sea NULL. Tenga en cuenta que no debe mostrar nombres de departamentos
que estén repetidos.
Consultas multitabla (Composición externa).
Resuelva todas las consultas utilizando las cláusulas LEFT JOIN y RIGHT JOIN.
1. Devuelve un listado con todos los empleados junto con los datos de los departamentos donde
trabajan. Este listado también debe incluir los empleados que no tienen ningún departamento
asociado.
2. Devuelve un listado donde sólo aparezcan aquellos empleados que no tienen ningún
departamento asociado.
3. Devuelve un listado donde sólo aparezcan aquellos departamentos que no tienen ningún
empleado asociado.
4. Devuelve un listado con todos los empleados junto con los datos de los departamentos donde
trabajan. El listado debe incluir los empleados que no tienen ningún departamento asociado y los
departamentos que no tienen ningún empleado asociado. Ordene el listado alfabéticamente por el
nombre del departamento.
5. Devuelve un listado con los empleados que no tienen ningún departamento asociado y los
departamentos que no tienen ningún empleado asociado. Ordene el listado alfabéticamente por el
nombre del departamento.
Consultas reflexivas.
1. Listado de todos los empleados que son jefes y el nombre del departamento del que cada
uno es jefe.
2. Listado de todos los empleados no jefes, el nombre de su jefe y el nombre del departamento
al que pertenece.
3. Listado de los empleados y su jefe del departamento I+D.
12
Y la base de datos está en el fichero: ventasdb.sql
Consultas multitablas (composición interna).
1. Devuelve un listado con el identificador, nombre y los apellidos de todos los clientes que
han realizado algún pedido. El listado debe estar ordenado alfabéticamente y se deben
eliminar los elementos repetidos.
2. Devuelve un listado que muestre todos los pedidos que ha realizado cada cliente. El
resultado debe mostrar todos los datos de los pedidos y del cliente. El listado debe mostrar
los datos de los clientes ordenados alfabéticamente.
3. Devuelve un listado que muestre todos los pedidos en los que ha participado un comercial.
El resultado debe mostrar todos los datos de los pedidos y de los comerciales. El listado
debe mostrar los datos de los comerciales ordenados alfabéticamente.
4. Devuelve un listado que muestre todos los clientes, con todos los pedidos que han realizado
y con los datos de los comerciales asociados a cada pedido.
5. Devuelve un listado de todos los clientes que realizaron un pedido durante el año 2017, cuya
cantidad esté entre 100 € y 1000 €.
6. Devuelve el nombre y los apellidos de todos los comerciales que ha participado en algún
pedido realizado por “Pepe Ruiz Santana”.
7. Devuelve el nombre de todos los clientes que han realizado algún pedido con el comercial
“Daniel Sáez Vega”.
Consultas multitablas (composición externa).
1. Devuelve un listado con todos los clientes junto con los datos de los pedidos que han
realizado. Este listado también debe incluir los clientes que no han realizado ningún pedido.
El listado debe estar ordenado alfabéticamente por el primer apellido, segundo apellido y
nombre de los clientes.
2. Devuelve un listado con todos los comerciales junto con los datos de los pedidos que han
realizado. Este listado también debe incluir los comerciales que no han realizado ningún
pedido. El listado debe estar ordenado alfabéticamente por el primer apellido, segundo
apellido y nombre de los comerciales.
3. Devuelve un listado que solamente muestre los clientes que no han realizado ningún pedido.
4. Devuelve un listado que solamente muestre los comerciales que no han realizado ningún
pedido.
5. Devuelve un listado con los clientes que no han realizado ningún pedido y de los
comerciales que no han participado en ningún pedido. Ordene el listado alfabéticamente por
los apellidos y el nombre. En en listado deberá diferenciar de algún modo los clientes y los
comerciales.
13