Usar subconsultas escalares o multivalor
Una subconsulta escalar es una instrucción SELECT interna dentro de una consulta externa, escrita para devolver un solo valor. Las subconsultas escalares se pueden usar en cualquier lugar de una instrucción T-SQL externa en la que se permita una expresión de un solo valor, como en una cláusula SELECT, una cláusula WHERE, una cláusula HAVING o incluso una cláusula FROM. También se pueden usar en instrucciones de modificación de datos, como UPDATE o DELETE.
Las subconsultas multivalor, como sugiere el nombre, pueden devolver más de una fila. Sin embargo, todavía devuelven una sola columna.
Subconsultas escalares
Imaginemos que desea recuperar los detalles del último pedido que se ha realizado, suponiendo que es el que tiene el valor SalesOrderID más alto.
Para buscar el valor SalesOrderID más alto, puede usar la consulta siguiente:
SELECT MAX(SalesOrderID)
FROM Sales.SalesOrderHeader
Esta consulta devuelve un valor único que indica el valor más alto de OrderID en la tabla SalesOrderHeader.
Para obtener los detalles de este pedido, es posible que tenga que filtrar la tabla SalesOrderDetails en función del valor devuelto por la consulta anterior. Puede realizar esta tarea anidando la consulta para recuperar el valor máximo de SalesOrderID dentro de la cláusula WHERE de una consulta que recupera los detalles del pedido.
SELECT SalesOrderID, ProductID, OrderQty
FROM Sales.SalesOrderDetail
WHERE SalesOrderID =
(SELECT MAX(SalesOrderID)
FROM Sales.SalesOrderHeader);
Para escribir una subconsulta escalar, tenga en cuenta las siguientes directrices:
- Para indicar una consulta como subconsulta, escríbala entre paréntesis.
- Se admiten varios niveles de subconsultas en Transact-SQL. En este módulo, solo se considerarán las consultas de dos niveles (una consulta interna dentro de una consulta externa), pero se admiten hasta 32 niveles.
- Si la subconsulta no devuelve filas (un conjunto vacío), el resultado de la subconsulta es NULL. Si es posible en su escenario que no se devuelva ninguna fila, debe asegurarse de que la consulta externa puede controlar correctamente un valor NULL, además de otros resultados esperados.
- Por lo general, la consulta interna debe devolver una sola columna. La selección de varias columnas en una subconsulta casi siempre es un error. La única excepción es si la subconsulta se indica con la palabra clave EXISTS.
Una subconsulta escalar se puede usar en cualquier lugar de una consulta donde se espera un valor, incluida la lista SELECT. Por ejemplo, podríamos ampliar la consulta que recuperó los detalles del pedido más reciente para incluir la cantidad media de elementos que se pide, de modo que podamos comparar la cantidad pedida en el pedido más reciente con la media de todos los pedidos.
SELECT SalesOrderID, ProductID, OrderQty,
(SELECT AVG(OrderQty)
FROM SalesLT.SalesOrderDetail) AS AvgQty
FROM SalesLT.SalesOrderDetail
WHERE SalesOrderID =
(SELECT MAX(SalesOrderID)
FROM SalesLT.SalesOrderHeader);
Subconsultas multivalor
Una subconsulta multivalor es adecuada para devolver resultados mediante el operador IN. En el ejemplo hipotético siguiente se devuelven los valores CustomerID y SalesOrderID de todos los pedidos realizados por los clientes de Canadá.
SELECT CustomerID, SalesOrderID
FROM Sales.SalesOrderHeader
WHERE CustomerID IN (
SELECT CustomerID
FROM Sales.Customer
WHERE CountryRegion = 'Canada');
En este ejemplo, si ejecutara solo la consulta interna, se devolvería una columna de valores CustomerID, con una fila para cada cliente de Canadá.
En muchos casos, las subconsultas multivalor se pueden escribir fácilmente mediante combinaciones. Por ejemplo, esta es una consulta que usa una combinación para devolver los mismos resultados del ejemplo anterior:
SELECT c.CustomerID, o.SalesOrderID
FROM Sales.Customer AS c
JOIN Sales.SalesOrderHeader AS o
ON c.CustomerID = o.CustomerID
WHERE c.CountryRegion = 'Canada';
¿Cómo se decide si se escribe una consulta que implica varias tablas como JOIN o con una subconsulta? A veces, solo depende de con qué se siente más cómodo. La mayoría de las consultas anidadas que se convierten fácilmente en JOIN realmente se convertirán en JOIN de forma interna. En el caso de estas consultas, no hay ninguna diferencia real al escribir la consulta de una manera frente a otra.
Una restricción que debe tener en cuenta es que cuando se usa una consulta anidada, los resultados devueltos al cliente solo pueden incluir columnas de la consulta externa. Por lo tanto, si tiene que devolver columnas de ambas tablas, debe escribir la consulta mediante JOIN.
Por último, hay situaciones en las que la consulta interna necesita realizar operaciones mucho más complicadas que las recuperaciones simples de nuestros ejemplos. La reescritura de subconsultas complejas mediante JOIN puede ser difícil. Para muchos desarrolladores de SQL, las subconsultas funcionan mejor para un procesamiento complicado, ya que le permite dividir el procesamiento en pasos más pequeños.