3 Consultas relacionadas¶
Introducción¶
Supongamos que queremos obtener todos los clientes que han realizado un pedido en una fecha determinada. Como se puede observar, en este caso se esta realizando un consulta que requiere información de dos tablas.
Cuando se require información de dos o más tablas, es necesario realizar una consulta relacional.
Existen tres formas de realizar consultas relacionas:
- Subconsultas
 - Asociaciones de tablas
 - Combinaciones de tablas
 
En cada una de ellas, se tendrá que validar si las tablas están o no relacionadas.
Subconsultas¶
Se trata de una técnica que permite utilizar el resultado de una tabla SELECT en otra consulta SELECT. Permite solucionar problemas en los que el mismo dato aparece dos veces. La sintaxis es:
SELECT lista_expresiones
FROM tablas
WHERE expresión OPERADOR
    ( SELECT lista_expresiones
      FROM tablas );
El operador puede ser >,<,>=,<=,!=, = o IN.
-- Obtiene los empleados cuyas pagas sean inferiores a lo que gana Martina.
SELECT nombre_empleado, paga
FROM EMPLEADOS
WHERE paga < ( SELECT paga
               FROM EMPLEADOS
               WHERE nombre_empleado='Martina');
Lógicamente el resultado de la subconsulta debe incluir el campo que estamos analizando.
Se pueden realizar esas subconsultas las veces que haga falta:
SELECT nombre_empleado, paga
FROM EMPLEADOS
WHERE paga < ( SELECT paga
               FROM EMPLEADOS
               WHERE nombre_empleado='Martina')
AND   paga > ( SELECT paga
               FROM EMPLEADOS
               WHERE nombre_empleado='Luis');
La última consulta obtiene los empleados cuyas pagas estén entre lo que gana Luis y lo que gana Martina. Una subconsulta que utilice los valores >,<,>=,… tiene que devolver un único valor, de otro modo ocurre un error. Pero a veces se utilizan consultas del tipo: mostrar el sueldo y nombre de los empleados cuyo sueldo supera al de cualquier empleado del departamento de ventas.
La subconsulta necesaria para ese resultado mostraría los sueldos del departamento de ventas. Pero no podremos utilizar un operador de comparación directamente ya que compararíamos un valor con muchos valores. La solución a esto es utilizar instrucciones especiales entre el operador y la consulta. Esas instrucciones son:
| Instrucción | Significado | 
|---|---|
| ANY | Compara con cualquier registro de la consulta.La instrucción es válida si hay un registro en la subconsulta que permite que la comparación sea cierta. | 
| ALL | Compara con todos los registros de la consulta.La instrucción resulta cierta si es cierta toda la comparación con los registros de la subconsulta. | 
| IN | NO usa comparador, ya que sirve para comprobar si un valor se encuentra en el resultado de la subconsulta | 
| NOT IN | Comprueba si un valor no se encuentra en una subconsulta | 
| EXISTS | Comprueba si los valores de la consulta 1 existen en la consulta 2 | 
| NOT EXISTS | Comprueba si los valores de la consulta 1 no existen en la consulta 2 | 
-- Obtiene el empleado que más cobra.
SELECT nombre, sueldo
FROM EMPLEADOS
WHERE sueldo >= ALL ( SELECT sueldo
                      FROM EMPLEADOS );
-- Obtiene los nombres de los empleados cuyos DNI están en la tabla de directivos.
-- Es decir, obtendrá el nombre de los empleados que son directivos.
SELECT nombre, sueldo
FROM EMPLEADOS
WHERE DNI IN ( SELECT DNI
               FROM DIRECTIVOS );
--- Obtiene el tipo de tiendas que existen en las ciudades
SELECT DISTINCT tipo FROM tiendas
  WHERE EXISTS (SELECT * FROM ciudades
                WHERE ciudades.tipo_tienda = tiendas.tipo);
Producto cruzado o cartesiano de tablas¶
Si deseamos obtener una lista de los clientes y de los pedidos, se podría hacer de esta forma:
Aunque la sintaxis es correcta ya que, efectivamente, en el apartado FROM se pueden indicar varias tareas separadas por comas, al ejecutarla produce un producto cruzado de las tablas. Es decir, aparecerán todos los registros de los pedidos relacionados con todos los registros de clientes (y no para cada cliente sus pedidos específicos). El producto cartesiano pocas veces es útil para realizar consultas. Nosotros necesitamos discriminar ese producto para que sólo aparezcan los registros de los pedidos relacionados con sus clientes correspondientes. A eso se le llama asociar tablas.
Asociaciones de tablas¶
La forma de realizar correctamente la consulta anterior (asociado los pedidos con los clientes que la realizaron) sería:
select id_cliente, nombre, cantidad, fecha
from cliente, pedido
where cliente.id = pedido.id_cliente
Nota
En el ejemplo anterior, se utiliza la notación tabla.columnapara evitar ambigüedades, es decir, que si el nombre del campo coinciden en ambas tablas no de error. En el caso anterior, para evitar repetir de forma continua el nombre de las tablas se puede usar un alias:
Aunque su uso no sea necesario, si se recomienda en cualquier caso, usando alias o no.
A la sintaxis WHERE se le pueden añadir condiciones sin más que encadenarlas con el operador AND.
select id_cliente, nombre, cantidad, fecha
from cliente, pedido
where id = id_cliente
and fecha = "2017%"
Finalmente indicar que se pueden enlazar más de dos tablas a través de sus claves principales y foráneas. Por cada relación necesaria entre tablas, aparecerá una condición (igualando la clave principal y la foránea correspondiente) en el WHERE.
Por ejemplo, si se quieren obtener todos los comerciales que han atendido el pedido de un cliente, se consultaría de la siguiente forma:
select c.nombre as nombre_cliente, co.nombre as nombre_comercial, cantidad, fecha
from cliente c, comercial co, pedido p
where c.id = p.id_cliente
and co.id = p.id_comercial
Relaciones sin igualdad¶
A las relaciones descritas anteriormente se las llama relaciones en igualdad (equijoins), ya que las tablas se relacionan a través de campos que contienen valores iguales en dos tablas. A veces esto no ocurre, en las tablas:
| Nombre | Sueldo | 
|---|---|
| Antonio | 18000 | 
| Marta | 21000 | 
| Sonia | 15000 | 
| Categoría | Sueldo Mínimo | Sueldo Máximo | 
|---|---|---|
| D | 6000 | 11999 | 
| C | 12000 | 17999 | 
| B | 18000 | 20999 | 
| A | 20999 | 80000 | 
En el ejemplo anterior podríamos averiguar la categoría a la que pertenece cada empleado, pero estas tablas poseen una relación que ya no es de igualdad.