Un Subqyuery Correlacionado tiene un método más complejo de ejecución
que un Subquery Single-Row y un Multiple-Row y es potencialmente más poderoso. Si
un Subquery hace referencia a columnas de la consulta padre, entonces el
resultado será dependiente de la consulta padre. Esto hace imposible evaluar el
subquery antes  de la evaluación de la
consulta padre. 
El Subquery Single-Row necesita ser ejecutado solo una vez, y el
resultado es sustituido en la consulta padre. Pero ahora considere una consulta
que desplegara todos los empleados que su salario es menor que el salario
promedio de su departamento. En este caso, el subquery debe ser ejecutado por
cada empleado para determinar el promedio de salario de su departamento; es
necesario pasar el id de departamento al subquery. Esto puede ser realizado
como sigue:
SELECT e1.employee_id, 
       e1.first_name, 
       e1.last_name, 
       e1.department_id, 
       e1.salary, 
       (SELECT
ROUND(AVG(e2.salary)) FROM employees e2 
WHERE E2.department_id = e1.department_id) PROMEDIO_DEPARTAMENTO
FROM   employees e1
WHERE  e1.salary < (SELECT
ROUND(AVG(e2.salary)) FROM employees e2 
WHERE E2.department_id = e1.department_id)
ORDER BY e1.employee_id;
En esta consulta el Subquery referencia las columna DEPARTMENT_ID de
la consulta padre, esto es señal que el subquery debe ser evaluado una vez por
cada empleado. El subquery se ejecutara utilizando el DEPARTMENT_ID de cada
empleado.
La ejecución se realiza en el siguiente orden:
1.      
Inicia en la primera fila de la tabla EMPLOYEES.
2.       Lee
el DEPARTMENT_ID y SALARY de la fila actual.
3.       Ejecuta
el Subquery utilizando el DEPARMENT_ID del paso 2.
4.       Compara
el resultado del paso 3 con el SALARY del paso 2 y devuelve la fila si el
SALARY es menor que el resultado.
5.       Avanza
a la siguiente fila de la tabla EMPLOYEES.
6.      
Y repite el paso 2.
Un Subquery Single-Row o Multiple-Row es evaluado una vez, antes de ser
evaluado la consulta padre. Un Subquery Correlacionado debe ser evaluado una
vez por cada fila de la consulta padre. Un Subquery Correlacionado puede ser un
Single o Multiple Row. Si los operadores de comparación son los apropiados.
SELECT employee_id, first_name, last_name, salary, (SELECT salary FROM
employees WHERE UPPER(last_name) LIKE '%TOBIAS%') salary_tobias
FROM   employees
WHERE  salary > (SELECT
salary FROM employees WHERE UPPER(last_name) LIKE '%TOBIAS%')
ORDER BY employee_id;
SELECT employee_id, first_name, last_name, salary, (SELECT salary FROM
employees WHERE UPPER(last_name) LIKE '%TAYLOR%') salary_tobias
FROM   employees
WHERE  salary > (SELECT
salary FROM employees WHERE UPPER(last_name) LIKE '%TAYLOR%')
ORDER BY employee_id;
SELECT employee_id, first_name, last_name, salary, (SELECT MAX(salary)
FROM employees WHERE UPPER(last_name) LIKE '%TAYLOR%') salary_tobias
FROM   employees
WHERE  salary > ALL (SELECT
salary FROM employees WHERE UPPER(last_name) LIKE '%TAYLOR%')
ORDER BY employee_id;
SELECT employee_id, first_name, last_name, salary, (SELECT MAX(salary)
FROM employees WHERE UPPER(last_name) LIKE '%TAYLOR%') salary_tobias
FROM   employees
WHERE  salary > (SELECT
MAX(salary) FROM employees WHERE UPPER(last_name) LIKE '%TAYLOR%')
ORDER BY employee_id;
SELECT
employee_id, first_name, last_name
FROM   employees
WHERE  manager_id IN (
                        SELECT e.employee_id
                        FROM   employees e
                               JOIN departments
d ON (e.department_id = d.department_id)
                               JOIN
locations   l ON (d.location_id =
l.location_id)
                               JOIN
countries   c ON (l.country_id =
c.country_id)
                        WHERE  c.country_name = 'United Kingdom'
                     );
SELECT
employee_id, first_name, last_name
FROM   employees
WHERE  manager_id IN (
                       SELECT employee_id
                       FROM   employees
                       WHERE  department_id IN (
                                                
SELECT department_id
                                                
FROM   departments
                                                
WHERE  location_id IN (
                                                                          SELECT location_id
                                                                         
FROM   locations
                                                                         
WHERE  country_id = 'UK'
                                                                       )
                                              
)
                     );
SELECT
job_title 
FROM   jobs 
       NATURAL JOIN employees 
GROUP BY
job_title
HAVING
AVG(salary) = (SELECT MAX(AVG(salary)) FROM employees GROUP BY job_id);
Comentarios
Publicar un comentario