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:

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 
   )