Subquery – Uma consulta aninhada em uma instrução SELECT, INSERT, UPDATE ou DELETE é chamada de Subquery (subconsulta). O limite máximo de aninhamento de uma Subquery é de 32 níveis, limite que pode variar de acordo com a complexidade das outras instruções que compõem a consulta e também da quantidade de memória disponível. Confira as principais características das Subqueries:

·         Pelo motivo de podermos trabalhar com consultas estruturadas, as Subqueries permitem que partes de um comando sejam separadas das demais;

·         Se uma instrução é permitida em um determinado local, este local aceita o uso de uma Subquery;

·         Uma Subquery, que pode ser incluída dentro de outra Subquery, é identificada por estar entre parênteses, o que a diferencia da consulta principal;

·         Quando temos uma Subquery aninhada na instrução SELECT externa, ela é formada por uma cláusula FROM regular com um ou mais nomes de visualização ou tabela, uma consulta SELECT regular junto dos componentes da lista de seleção regular e as cláusulas opcionais WHERE, HAVING e GROUP BY.

·         Uma consulta SELECT de uma Subquery não pode ter uma cláusula FOR BROWSE ou COMPUTE incluída. Além disso, caso um cláusula TOP seja especificada, essa consulta (que está sempre entre parênteses) pode incluir apenas uma cláusula ORDER BY;

·         As Subqueries podem ser classificadas em: 1- Subqueries incluídas junto de um operador de comparação não modificado e que devem retornar um valor único, 2- Subqueries que são testes de existência acrescentados com EXISTS, e 3- Subqueries que operam em listas introduzidas com IN ou que foram alteradas por um operador de comparação com ALL ou ANY;

·         Por oferecer diversas formas de obtermos resultados, as Subqueries eliminam a necessidade de usarmos cláusulas JOIN e UNION de maior complexidade;

·         Uma Subquery também é chamada de INNER QUERY ou INNER SELECT;

·         Chamamos de OUTER QUERY ou OUTER SELECT a instrução que possui determinada Subquery;

·         Como alternativa, podemos formular diversas instruções do Transact-SQL com Subqueries como JOINS;

·         Se compararmos duas instruções: uma que possua uma Subquery e outra semanticamente semelhante, mais que não possua Subquery, não notaremos muitas diferenças de desempenho. No entanto, uma JOIN apresenta melhor desempenho nas situações em que se precisa verificar a existência;

·         As colunas de uma tabela não poderão ser incluídas na saída, ou seja, na lista de seleção da OUTER QUERY, caso esta tabela apareça apenas em uma Subquery e não na OUTER QUERY.

·         Confira a seguir os formatos normalmente apresentados pelas instruções que possuem uma Subquery:

- WHERE expressão [NOT] IN (Subquery);

- WHERE expressao operador_de_comparacao [ANY|ALL] (Subquery);

- WHERE [NOT] EXISTS (Subquery).

 Subqueries usando IN/NOT – Para entendermos melhor os conceitos de Subqueries, nada melhor do que exemplos práticos não é mesmo? Então, observe as tabelas Cargo e Funcionario:


 Perceba que aqui temos um relacionamento entre as tabelas, onde cada funcionário tem seu cargo definido pelo Id da tabela Cargo. Perceba também que não temos nenhum funcionário com o cargo Programador Sr. referente ao Id 5. Isso é claro, porque a tabela Funcionario não contém este Id.

 Caso precisemos informar ao usuário qual Cargo não está vinculado a algum Funcionário devemos usar a seguinte instrução:

SELECT IDCARGO AS Id, NOMECARGO AS Cargo FROM CARGO

 WHERE IDCARGO NOT IN (SELECT IDCARGO FROM FUNCIONARIO)

 O resultado será o seguinte:


 Ao executarmos o segundo SELECT do comando acima, serão obtidos os dados que, por sua vez, serão armazenados na memória. Assim que outro SELECT for executado, os dados armazenados devido à execução do SELECT anterior irão se confrontar, o que resultará na exibição da imagem acima, que é o cargo cujo código não está presente na tabela Funcionario, ou seja, o Id de cargo 5, referente ao Programador Sr.

 Dito isto, podemos concluir que o SQL Server sempre executa o Select de dentro primeiro para depois executar o Select de fora.

 Da mesma forma que no exemplo anterior, se usarmos a cláusula IN, teremos somente os Cargos vinculados aos Funcionários:


 Simples né?

 Na próxima e última parte de nosso artigo veremos mais alguns exemplos, com os operadores Max(), Min() e Count(). Veremos também como realizar Update e Delete com Subqueries, aguardem!

 Assim finalizo o artigo. Muito obrigado a todos!

 Um abraço, e até o próximo artigo.

 Wellington Balbo de Camargo

 wellingtonbalbo@gmail.com