subconsultas-subqueries-sql

Subconsultas en SQL

  • 4 min

Una Subqueries es una sentencia SELECT anidada dentro de otra sentencia SELECT, INSERT, UPDATE o DELETE.

A veces, para responder a una pregunta compleja, primero necesitamos responder a una pregunta más simple. Imagina que quieres saber:

“¿Qué productos son más caros que el precio promedio?”.

Para responder a esto, primero necesitas saber cuál es el precio promedio, y luego comparar cada producto con ese valor.

En T-SQL, podemos hacer esto en un solo paso utilizando Subconsultas (Subqueries). Básicamente, es meter una consulta SELECT dentro de otra consulta principal.

La subconsulta (la de dentro) se ejecuta primero, y su resultado es utilizado por la consulta externa para completar su trabajo.

Subconsultas escalares

Son las más sencillas. La subconsulta devuelve una única fila y una única columna (un solo valor). Podemos usarla en cualquier lugar donde usaríamos un número o un texto (en el WHERE, en el SELECT, etc.).

Pongamos un ejemplo, productos más caros que el promedio.

SELECT Nombre, Precio
FROM Productos
WHERE Precio > (
    -- Esta es la subconsulta. Devuelve un solo número (ej: 50.00)
    SELECT AVG(Precio) 
    FROM Productos
);
Copied!

Aquí, SQL Server calcula primero el promedio (digamos 50€) y luego ejecuta la consulta externa como si fuera WHERE Precio > 50.

Subconsultas de lista

A veces la subconsulta devuelve una lista de valores (una columna, varias filas). En este caso, no podemos usar operadores como =, > o <. Necesitamos usar el operador IN.

Por ejemplo, clientes que han comprado productos de la categoría “Electrónica”.

SELECT Nombre, Apellido
FROM Clientes
WHERE ClienteID IN (
    -- Subconsulta: Devuelve una lista de IDs de clientes
    SELECT DISTINCT ClienteID
    FROM Pedidos P
    INNER JOIN DetallesPedido D ON P.PedidoID = D.PedidoID
    INNER JOIN Productos Pr ON D.ProductoID = Pr.ProductoID
    WHERE Pr.Categoria = 'Electrónica'
);
Copied!

La subconsulta devuelve una lista de IDs y la consulta externa filtra a los clientes cuyo ID esté en esa lista.

Subconsultas correlacionadas

En los ejemplos anteriores, la subconsulta era independiente: se ejecutaba una vez, devolvía un resultado y listo.

En una Subconsulta Correlacionada, la consulta interna depende de la consulta externa. Esto significa que la subconsulta se ejecuta una vez por cada fila de la consulta principal.

Por ejemplo, Empleados que ganan más que el promedio de su propio departamento.

SELECT Nombre, Salario, DepartamentoID
FROM Empleados E1
WHERE Salario > (
    SELECT AVG(Salario)
    FROM Empleados E2
    WHERE E2.DepartamentoID = E1.DepartamentoID -- Aqui esta la gracia
);
Copied!

Fíjate en E2.DepartamentoID = E1.DepartamentoID.

  1. SQL coge al primer empleado (Juan, Ventas).
  2. Pasa el ID ‘Ventas’ a la subconsulta.
  3. Calcula el promedio solo de Ventas.
  4. Compara el salario de Juan con ese promedio.
  5. Repite para el siguiente empleado.

Rendimiento: Las subconsultas correlacionadas pueden ser lentas en tablas muy grandes, porque obligan al motor a ejecutar la subconsulta miles de veces (N+1 queries). Úsalas con cuidado.

Subconsultas en el FROM

También podemos usar el resultado de una subconsulta como si fuera una tabla temporal sobre la que hacer más consultas. Esto se llama Tabla Derivada.

Es obligatorio ponerle un Alias.

SELECT T.Categoria, T.PromedioPrecio
FROM (
    -- Tabla virtual generada al vuelo
    SELECT Categoria, AVG(Precio) as PromedioPrecio
    FROM Productos
    GROUP BY Categoria
) AS T -- El alias es obligatorio aquí
WHERE T.PromedioPrecio > 100;
Copied!

Aunque esto funciona, en SQL moderno solemos preferir usar CTEs (Common Table Expressions) por legibilidad, algo que veremos en su propio artículo, pero el concepto es el mismo.