Consultas anidadas en SQL
El lenguaje SQL le permite anidar una consulta dentro de otra consulta. Esto hace posible escribir una consulta muy grande que hará algo grande y complejo, aunque la legibilidad del código se reduce considerablemente.
Dependiendo de cuántos valores devuelvan las subconsultas, el área donde se pueden aplicar cambia. Hay tres opciones en total:
- La subconsulta devuelve un único valor (una columna y una fila).
- La subconsulta devuelve una lista de valores (una tabla con una columna).
- La subconsulta devuelve una tabla (muchas columnas, cualquier número de filas).
Veamos un ejemplo para cada caso.
Subconsulta con resultado escalar
Busquemos una lista de todos nuestros empleados de la tabla de empleados cuyo salario sea superior al promedio de la empresa. ¿Como podemos hacerlo?
Podemos filtrar fácilmente a los empleados comparando su salario con el promedio si lo conocemos de antemano. Al mismo tiempo, ya hemos escrito una consulta que nos permite calcular el salario promedio de los empleados de la empresa. Recordémoslo:
SELECT AVG(salary) FROM employee
Entonces MySQL nos devolvió el valor: 76833.3333 .
¿Cómo encontrar ahora una lista de todos los empleados cuyo salario está por encima del promedio? También es muy simple:
SELECT * FROM employee
WHERE salary > 76833.3333
El resultado de esta consulta será:
identificación | nombre | ocupación | salario |
---|---|---|---|
1 | ivanov ivan | Programador | 100000 |
2 | petrov petr | Programador | 80000 |
4 | Rabinovich Moisha | Director | 200000 |
Y ahora simplemente combinamos ambas solicitudes sustituyendo la primera solicitud en lugar del valor 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
El resultado de esta consulta será el mismo:
identificación | nombre | ocupación | salario |
---|---|---|---|
1 | ivanov ivan | Programador | 100000 |
2 | petrov petr | Programador | 80000 |
4 | Rabinovich Moisha | Director | 200000 |
Subconsulta con lista de valores
¿Recuerda una vez que teníamos una tarea: encontrar todos los registros de una tabla para los que no hay registros correspondientes de otra?
También estaba esta foto:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Si no me equivoco, la tarea es la siguiente: mostrar una lista de todos los empleados de la tabla de empleados para los que no hay tareas en la tabla de tareas .
Busquemos también una solución en dos pasos.
Primero, escribamos una consulta que devuelva la identificación de todos los empleados que tienen tareas en la tabla de tareas. Solo recuerda dos cosas:
- elimine los duplicados: utilice la palabra clave DISTINCT.
- eliminar valores NULL del resultado.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
Y aquí tenemos un hermoso resultado de tal solicitud:
ID de empleado |
---|
1 |
2 |
5 |
4 |
6 |
Escribámoslo temporalmente por conveniencia como una secuencia: 1,2,5,4,6. Ahora escribamos una segunda consulta en la tabla de empleados, que devolverá una lista de empleados cuya identificación no está incluida en la primera lista:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
Y el resultado de esta consulta:
identificación | nombre | ocupación | salario | edad | Fecha de Ingreso |
---|---|---|---|---|---|
3 | Sergey Ivanov | Ensayador | 40000 | treinta | 2014-01-01 |
Y ahora, como en el ejemplo anterior, puede combinar ambas solicitudes simplemente reemplazando el cuerpo de la primera solicitud en lugar de la lista de id.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)