- 18/02/2018
- 21 minutos para ler
-
- W
- M
- T
- M
- j
-
+3
Aplica-se a: SQL Server (todas as versões com suporte) Banco de dados SQL do Azure Instância gerenciada do Azure SQL Azure Synapse Analytics Data Warehouse paralelo
Uma subconsulta é uma consulta aninhada dentro de um SELECT
, INSERT
, UPDATE
ou DELETE
declaração ou dentro de outra subconsulta. Uma subconsulta pode ser usada em qualquer lugar onde uma expressão seja permitida. Neste exemplo, uma subconsulta é usada como uma expressão de coluna chamada MaxUnitPrice em uma instrução SELECT.
Fundamentos da subconsulta
Uma subconsulta também é chamada de consulta interna ou seleção interna, enquanto a instrução que contém uma subconsulta também é chamada de consulta externa ou seleção externa.
Muitas instruções Transact-SQL que incluem subconsultas podem ser formuladas alternativamente como junções. Outras perguntas podem ser feitas apenas com subconsultas. No Transact-SQL, geralmente não há diferença de desempenho entre uma instrução que inclui uma subconsulta e uma versão semanticamente equivalente que não inclui. No entanto, em alguns casos em que a existência deve ser verificada, uma junção produz um melhor desempenho. Caso contrário, a consulta aninhada deve ser processada para cada resultado da consulta externa para garantir a eliminação de duplicatas. Nesses casos, uma abordagem de junção produziria melhores resultados. A seguir está um exemplo que mostra uma subconsulta SELECT
e uma junção SELECT
que retorna o mesmo conjunto de resultados:
Uma subconsulta aninhada na instrução SELECT externa tem os seguintes componentes:
- Uma consulta
SELECT
regular incluindo os componentes normais da lista de seleção. - Uma cláusula
FROM
regular incluindo um ou mais nomes de tabela ou visualização. - Um
WHERE
cláusula. - Uma cláusula
GROUP BY
opcional. - Uma .
A consulta SELECT de uma subconsulta está sempre entre parênteses. Não pode incluir uma cláusula COMPUTE
ou FOR BROWSE
e pode incluir apenas uma cláusula ORDER BY
quando uma cláusula TOP também é especificada.
Uma subconsulta pode ser aninhada dentro da cláusula WHERE
ou HAVING
de uma cláusula externa SELECT
, INSERT
, UPDATE
ou DELETE
instrução ou dentro de outra subconsulta. É possível até 32 níveis de aninhamento, embora o limite varie com base na memória disponível e na complexidade de outras expressões na consulta. Consultas individuais podem não suportar aninhamento em até 32 níveis. Uma subconsulta pode aparecer em qualquer lugar em que uma expressão possa ser usada, se retornar um único valor.
Se uma tabela aparecer apenas em uma subconsulta e não na consulta externa, as colunas dessa tabela não podem ser incluídas no output (a lista de seleção da consulta externa).
As instruções que incluem uma subconsulta geralmente têm um destes formatos:
- WHERE expressão IN (subconsulta)
- WHERE expressão comparação_operador (subconsulta)
- WHERE EXISTS (subconsulta)
Em algumas instruções Transact-SQL, a subconsulta pode ser avaliada como se fosse uma consulta. Conceitualmente, os resultados da subconsulta são substituídos na consulta externa (embora não seja necessariamente assim que o SQL Server realmente processa as instruções Transact-SQL com subconsultas).
Existem três tipos básicos de subconsultas. Aqueles que:
- operam em listas introduzidas com
IN
, ou aqueles que um operador de comparação modificou porANY
ouALL
. - São introduzidos com um operador de comparação não modificado e devem retornar um único valor.
- Os testes de existência são introduzidos com
EXISTS
.
Regras de subconsulta
Uma subconsulta está sujeita às seguintes restrições:
- A lista de seleção de uma subconsulta introduzida com um operador de comparação pode incluir apenas uma expressão ou nome de coluna (exceto que
EXISTS
eIN
operam emSELECT *
ou uma lista, respectivamente). - Se a cláusula
WHERE
de uma consulta externa incluir um nome de coluna, deve ser compatível com a junção com a coluna na lista de seleção da subconsulta. - Os tipos de dados ntext, text e image não podem ser usados na lista de seleção de subconsultas.
- Porque eles devem retornar um único valor, as subconsultas introduzidas por um operador de comparação não modificado (um não seguida pela palavra-chave ANY ou ALL) não pode incluir as cláusulas
GROUP BY
eHAVING
. - As cláusulas
DISTINCT
não pode ser usada com subconsultas que incluem GROUP BY. -
COMPUTE
eINTO
não podem ser especificadas. -
ORDER BY
só pode ser especificado quandoTOP
também é especificado. - Uma visualização criada usando uma subconsulta não pode ser atualizada.
- A lista de seleção de uma subconsulta introduzida com
EXISTS
, por convenção, tem um asterisco ( *) em vez de um único nome de coluna. As regras para uma subconsulta introduzida comEXISTS
são iguais às de uma lista de seleção padrão, porque uma subconsulta introduzida comEXISTS
cria uma existência testa e retorna TRUE ou FALSE, em vez de dados.
Nomes de coluna de qualificação em subconsultas
No exemplo a seguir, a coluna BusinessEntityID em da consulta externa é implicitamente qualificada pelo nome da tabela na cláusula FROM
(Sales.Store) da consulta externa. A referência ao CustomerID na lista de seleção da subconsulta é qualificada pela cláusula FROM
da subconsulta, ou seja, pela tabela Sales.Customer.
A regra geral é que os nomes das colunas em uma instrução são implicitamente qualificados pela tabela referenciada na cláusula FROM
no mesmo nível. Se uma coluna não existir na tabela referenciada na cláusula FROM
de uma subconsulta, ela é implicitamente qualificada pela tabela referenciada no FROM
cláusula da consulta externa.
Aqui está a aparência da consulta com essas suposições implícitas especificadas:
Nunca está errado para declarar o nome da tabela explicitamente, e sempre é possível substituir suposições implícitas sobre nomes de tabela com qualificações explícitas.
Importante
Se uma coluna é referenciada em uma subconsulta que não existe na tabela referenciada pela subconsulta “s FROM
cláusula, mas existe em uma tabela referenciada pela consulta externa” s FROM
cláusula, a consulta é executada sem erros. O SQL Server qualifica implicitamente a coluna na subconsulta com o nome da tabela na consulta externa.
Vários níveis de aninhamento
Uma subconsulta pode incluir uma ou mais subconsultas. Qualquer número de subconsultas pode ser aninhado em uma instrução.
A consulta a seguir encontra os nomes de funcionários que também são vendedores.
Aqui está o conjunto de resultados.
A consulta mais interna retorna os IDs dos vendedores. A consulta no próximo nível superior é avaliada com esses IDs de vendedores e retorna os números de ID de contato dos funcionários. Finalmente, a consulta externa usa os IDs de contato para encontrar os nomes dos funcionários.
Você também pode expressar esta consulta como uma junção:
Muitas consultas podem ser avaliadas executando a subconsulta uma vez e substituindo o valor ou valores resultantes na cláusula WHERE
da consulta externa. Em consultas que incluem uma subconsulta correlacionada (também conhecida como subconsulta de repetição), a subconsulta depende da consulta externa para seus valores. Isso significa que a subconsulta é executada repetidamente, uma para cada linha que pode ser selecionada pela consulta externa. Esta consulta recupera uma instância do nome e sobrenome de cada funcionário para o qual o bônus na tabela SalesPerson é 5000 e para o qual o os números de identificação dos funcionários correspondem nas tabelas Employee e SalesPerson.
Aqui está o conjunto de resultados.
A subconsulta anterior nesta instrução não pode ser avaliada independentemente da consulta externa. Ela precisa de um valor para Employee.BusinessEntityID, mas esse valor muda conforme o SQL Server examina diferentes linhas em Employee.
É exatamente assim que isso a consulta é avaliada: o SQL Server considera cada linha da tabela Employee para inclusão nos resultados, substituindo o valor em cada linha na consulta interna. Por exemplo, se o SQL Server primeiro examinar a linha para Syed Abbas
, a variável Employee.BusinessEntityID assume o valor 285, que o SQL Server substitui utes na consulta interna.
O resultado é 0 (Syed Abbas
não recebeu um bônus porque é não é um vendedor), então a consulta externa avalia como:
Como isso é falso, a linha para Syed Abbas
não está incluído nos resultados.