Databases
T01-011-02 Subconsultas en cláusulas distintas al WHERE (opcional)
Enunciado
Como dijimos anteriormente, podemos utilizar subconsultas en cláusulas como
HAVINGoFROM.La utilización de una subconsulta en una clásula
HAVING, no difiere de la ya explicada en la cláusulaWHERE, por lo que nos centraremos, en este apartado a su utilización en la clásulaFROM.Subcobsultas en
FROM.Recordemos que, en la clásula
FROM, debemos hacer referencia a las tablas que vamos a utilizar en la consulta.
...
FROM HR.employees JOIN HR.departments USING...En el ejemplo anterior employees y departments son tablas del esquema HR.
Observemos también que el resultado de las sentencias
SELECTse muestran en formato tabla, lo que las convierte en objetos que se pueden referenciar en la cláusulaFROM, siempre y cuando le asignemos un alias de tabla.Ejemplo:
Vamos a construir una sentencia que muestre los empleados que tienen una antigüedad mayor que los mejor pagados de su departamento.
Igual que haría cualquier persona que no dispusiera de una base de datos, buscaría en primer lugar quiénes son los mejor pagados de cada departamento y cuál es su fecha de contratación:
SELECT FIRST_NAME, DEPARTMENT_ID, HIRE_DATE
FROM HR.employees
WHERE (DEPARTMENT_ID, SALARY) IN (
SELECT DEPARTMENT_ID, MAX(SALARY)
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
)
ORDER BY DEPARTMENT_IDEl resultado sería una tabla como la siguiente:
FIRST_NAME DEPARTMENT_ID HIRE_DATE Jennifer 10 17-SEP-03 Michael 20 17-FEB-04 Den 30 07-DEC-02 ... ... ... En contenidos posteriores del curso, veremos que esta tabla la podríamos incluso guardar en la base de datos. De momento, únicamente le vamos a poner un alias (MejorPagados), para poder referenciarla.
Disponiendo de esa tabla, ya podemos buscar a los empleados con una antigüedad mayor que los MejorPagados de su departamento:
SELECT DISTINCT EMP.FIRST_NAME, EMP.LAST_NAME, EMP.DEPARTMENT_ID, EMP.HIRE_DATE
FROM HR.EMPLOYEES EMP JOIN MEJORPAGADOS ON (EMP.DEPARTMENT_ID = MEJORPAGADOS.DEPARTMENT_ID)
WHERE EMP.HIRE_DATE < MEJORPAGADOS.HIRE_DATE
ORDER BY EMP.DEPARTMENT_ID, EMP.LAST_NAMEYa! ya! Es cierto que si ejecutamos la consulta anterior, el resultado sería: ORA-00942: table or view does not exist
Lo único que nos queda hacer es poner la consulta que utilizamos para obtener la tabla de los MejorPagados, como la subconsulta que define dicha tabla:
SELECT DISTINCT EMP.FIRST_NAME, EMP.LAST_NAME, EMP.DEPARTMENT_ID, EMP.HIRE_DATE
FROM HR.EMPLOYEES EMP JOIN (
SELECT FIRST_NAME, DEPARTMENT_ID, HIRE_DATE
FROM HR.employees
WHERE (DEPARTMENT_ID, SALARY) IN (
SELECT DEPARTMENT_ID, MAX(SALARY)
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
)
ORDER BY DEPARTMENT_ID
) MEJORPAGADOS ON (EMP.DEPARTMENT_ID = MEJORPAGADOS.DEPARTMENT_ID)
WHERE EMP.HIRE_DATE < MEJORPAGADOS.HIRE_DATE
ORDER BY EMP.DEPARTMENT_ID, EMP.LAST_NAMEAhora sí se obtienen los datos que buscábamos:
FIRST_NAME LAST_NAME DEPARTMENT_ID HIRE_DATE Sarah Bell 50 04-FEB-04 Alexis Bull 50 20-FEB-05 ... ... ... ... David Austin 60 25-JUN-05 Ellen Abel 80 11-MAY-04 Janette King 80 30-JAN-04 ... ... ... ... Las posibilidades de anidar subconsultas son infinitas (o casi) y nos permiten resolver consultas acercándonos poco a poco a la solución.
Ejercicio:
En el esquema HR aparecen empleados cuyo salario coincide con el mínimo establecido para el trabajo que realizan. A la consulta correspondiente a estos empleados la vamos a nombrar como MinimamentePagados.
Averigua quiénes son los jefes de los departamentos en los que trabajan estos empleados por si se les solicitara que les incrementaran el salario. Ordena a estos jefes de departamento según el nombre de su departamento.
Tipo
Solución
SELECT FIRST_NAME, LAST_NAME, DEPARTMENT_NAME
FROM HR.EMPLOYEES JOIN HR.DEPARTMENTS ON(EMPLOYEES.EMPLOYEE_ID = DEPARTMENTS.MANAGER_ID) JOIN (
SELECT DISTINCT JOB_TITLE, DEPARTMENT_ID
FROM HR.EMPLOYEES JOIN HR.JOBS USING(JOB_ID)
WHERE SALARY = MIN_SALARY
) MINIMAMENTEPAGADOS ON (DEPARTMENTS.DEPARTMENT_ID = MINIMAMENTEPAGADOS.DEPARTMENT_ID)
ORDER BY DEPARTMENT_NAME
Prueba
LibrerÃas (Onfly databases)

