Skip to content

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:

select *
from cliente, pedido

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:

select id_cliente, nombre, cantidad, fecha
from cliente c, pedido p
where c.id = p.id_cliente
Aunque en este caso no existe ambigüedad ya que ambas columnas tienen diferentes nombres, se podría entonces omitir las tablas:

select id_cliente, nombre, cantidad, fecha
from cliente, pedido
where id = id_cliente

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.

SELECT E.empleado, E.sueldo, C.categoria
FROM EMPLEADOS E, CATEGORÍAS C
WHERE E.sueldo BETWEEN C.sueldo_mínimo AND C.sueldo_máximo;