Utilize subconsultas escalares ou com valores múltiplos

Concluído

Uma subconsulta escalar é uma instrução SELECT interna dentro de uma consulta externa, escrita para retornar um único valor. Subconsultas escalares podem ser usadas em qualquer lugar em uma instrução T-SQL externa em que uma expressão de valor único seja permitida— como em uma cláusula SELECT, uma cláusula WHERE, uma cláusula HAVING ou até mesmo uma cláusula FROM. Elas também podem ser usadas em instruções de modificação de dados, como UPDATE ou DELETE.

Subconsultas com valores múltiplos, como o nome sugere, podem retornar mais de uma linha. No entanto, ainda retornam uma única coluna.

Subconsultas escalares

Suponha que você queira recuperar os detalhes do último pedido que foi feito, supondo que ele seja o de valor SalesOrderID mais alto.

Para encontrar o valor SalesOrderID mais alto, você pode usar a seguinte consulta:

SELECT MAX(SalesOrderID)
FROM Sales.SalesOrderHeader

Essa consulta retorna um único valor, que indica o valor mais alto para uma OrderID na tabela SalesOrderHeader.

Para obter os detalhes desse pedido, talvez seja necessário filtrar a tabela SalesOrderDetails com base no valor retornado pela consulta acima. Você pode concluir essa tarefa aninhando a consulta para recuperar o SalesOrderID máximo dentro da cláusula WHERE de uma consulta que recupera os detalhes do pedido.

SELECT SalesOrderID, ProductID, OrderQty
FROM Sales.SalesOrderDetail
WHERE SalesOrderID = 
   (SELECT MAX(SalesOrderID)
    FROM Sales.SalesOrderHeader);

Para escrever uma subconsulta escalar, considere as seguintes diretrizes:

  • Para denotar uma consulta como uma subconsulta, coloque-a entre parênteses.
  • Há suporte para vários níveis de subconsulta no Transact-SQL. Neste módulo, consideraremos apenas consultas de dois níveis (uma consulta interna dentro de uma consulta externa), mas há suporte para até 32 níveis.
  • Se a subconsulta não retornar linhas (um conjunto vazio), o resultado da subconsulta será NULL. Se for possível em seu cenário que nenhuma linha seja retornada, você deverá garantir que sua consulta externa possa lidar normalmente com um NULL, e com outros resultados esperados.
  • A consulta interna geralmente deve retornar uma única coluna. Selecionar várias colunas em uma subconsulta é quase sempre um erro. A única exceção será se a subconsulta for introduzida com a palavra-chave EXISTS.

Uma subconsulta escalar pode ser usada em qualquer lugar em uma consulta em que um valor é esperado, incluindo a lista SELECT. Por exemplo, podemos estender a consulta que recuperou detalhes do pedido mais recente para incluir a quantidade média de itens pedida, para que possamos comparar a quantidade pedida no pedido mais recente com a média de todos os 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 com valores múltiplos

Uma subconsulta com vários valores é adequada para retornar resultados usando o operador IN. O exemplo hipotético a seguir retorna os valores CustomerID, SalesOrderID para todos os pedidos feitos por clientes no Canadá.

SELECT CustomerID, SalesOrderID
FROM Sales.SalesOrderHeader
WHERE CustomerID IN (
    SELECT CustomerID
    FROM Sales.Customer
    WHERE CountryRegion = 'Canada');

Neste exemplo, se você fosse executar apenas a consulta interna, seria retornada uma coluna de valores CustomerID, com uma linha para cada cliente no Canadá.

Em muitos casos, subconsultas com vários valores podem ser facilmente escritas usando junções. Por exemplo, aqui está uma consulta que usa uma junção para retornar os mesmos resultados do exemplo 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';

Então, como decidir se devemos escrever uma consulta que envolve várias tabelas como um JOIN ou uma subconsulta? Às vezes, depende apenas de qual opção o deixa mais confortável. A maioria das consultas aninhadas que são facilmente convertidas em JOINS será realmente convertida em uma junção internamente. Para essas consultas, não há diferença real em escrever a consulta de uma maneira ou de outra.

Uma restrição que você deve ter em mente é que, ao usar uma consulta aninhada, os resultados retornados para o cliente só podem incluir colunas da consulta externa. Portanto, se você precisar retornar colunas de ambas as tabelas, deverá escrever a consulta usando um JOIN.

Por fim, há situações em que a consulta interna precisa executar operações muito mais complicadas do que as recuperações simples em nossos exemplos. Reescrever subconsultas complexas usando um JOIN pode ser difícil. Muitos desenvolvedores de SQL acreditam que subconsultas funcionam melhor para processamento complicado, porque elas permitem dividir o processamento em etapas menores.