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