O que é uma Subconsulta SQL (Subquery)

O que é uma Subconsulta SQL (Subquery)

Uma subconsulta é uma consulta embutida dentro de outra consulta, de forma aninhada, passando os resultados da consulta mais interna para a consulta mais externa por meio de uma cláusula WHERE ou de uma cláusula HAVING.

Desta forma, é possível restringir mais ainda os dados retornados por uma consulta, permitindo a criação de filtros bastante aprimorados. A subconsulta retorna os dados que serão empregado pela consulta “principal”, alimentando-a com informações a serem utilizadas como condições de filtragem.

Podemos utilizar subconsultas não apenas em consultas com a cláusula SELECT, mas também em operações INSERT, UPDATE e DELETE.

Quando usamos uma subconsulta em uma query, a subconsulta é resolvida primeiro, e então a consulta externa (principal) é resolvida de acordo com o resultado retornado pela subconsulta (subquery).

Regras gerais para aplicação de subconsultas

Algumas regras gerais precisam se seguidas para que seja possível empregar subconsultas. Entre elas, temos:

  • A subconsulta pode ter apenas uma única coluna em sua cláusula SELECT, exceto quando a consulta principal tiver múltiplas colunas para comparação com as colunas selecionadas
  • Se a subconsulta retornar mais de uma linha de dados, é necessário usar operadores de valores múltiplos, como o operador lógico IN
  • As subconsultas são escritas dentro de parênteses
  • Não é possível usar a cláusula ORDER BY em uma subconsulta – mas a consulta principal pode.
  • É possível usar uma cláusula GROUP BY em uma subconsulta.
  • Não podemos usar o operador BETWEEN com uma subconsulta (na consulta principal), mas podemos usar esse operador dentro da subconsulta.

Sintaxe Básica de uma Subconsulta SQL

A sintaxe básica para a criação de uma subconsulta SQL é a seguinte:

SELECT coluna(s)
FROM tabela(s)
WHERE coluna operador (SELECT coluna
                       FROM tabela WHERE condições);

Onde operador pode ser qualquer operador lógico ou relacional, como >, <, >= ,<= ,=, <>, IN, NOT, AND, OR, etc.

Vejamos exemplos de aplicação de subconsultas SQL, usando o SGBD MySQL Server.

1. Subconsulta com operação SELECT

Vamos efetuar uma consulta à tabela de livros de nosso banco de dados db_biblioteca, retornando os livros (tbl_livro) publicados pela editora Wiley (tbl_editora), porém usando uma subconsulta em vez de usar INNER JOIN:

SELECT NomeLivro, PrecoLivro, IdEditora
FROM tbl_livro
WHERE IdEditora = 
    (SELECT IdEditora
     FROM tbl_editora
     WHERE NomeEditora = 'Wiley');

Resultado:

Subconsulta SQL com MySQL

2. Subconsulta com operação INSERT INTO

Podemos usar subconsultas também com a instrução de inserção de registros INSERT INTO, e outras instruções de linguagem de manipulação de dados (DML). Com a instrução INSERT INTO, os dados retornados por uma subconsulta são usados para realizar a inserção de um registro em outra tabela.

Sintaxe:

INSERT INTO tabela (colunas)
                   (SELECT coluna(s)
                   FROM tabela(s)
                   WHERE coluna operador valor);

Exemplo: Vamos criar uma tabela de exemplo chamada de LivrosAssuntos, contendo os campos ID, NomeLivro e NomeAssunto:

CREATE TABLE LivrosAssuntos (
  ID TINYINT PRIMARY KEY AUTO_INCREMENT,
  NomeLivro VARCHAR(50),
  NomeAssunto VARCHAR(40)
)

Usando uma subconsulta, vamos popular esta nova tabela com os livros que tenham mais de 600 páginas e seus respectivos assuntos:

INSERT INTO LivrosAssuntos (NomeLivro, NomeAssunto)
  (SELECT L.NomeLivro, A,NomeAssunto
  FROM tbl_livro L
  INNER JOIN tbl_assunto A
    ON L.IdAssunto = A.IdAssunto
  WHERE L.NumPaginas >= 600);

Após executar o comando, efetuamos uma consulta à nova tabela para verificar se os dados foram inseridos com sucesso:

SELECT * FROM LivrosAssuntos

Resultado:

Inserção de dados com subconsulta SQL (subquery)

3. Subconsulta com operação UPDATE

Também podemos usar uma subconsulta com uma instrução UPDATE, permitindo atualizar os valores de registros de uma tabela com base no resultado retornado pela subconsulta.

Sintaxe:

UPDATE tabela
SET coluna(s) = valor
WHERE coluna operador (SELECT coluna(s)
                       FROM tabela
                       WHERE coluna operador valor);

Exemplo: Vamos aumentar os preços dos livros da editora Microsoft Press em 12% usando a declaração UPDATE. Como não sabemos o ID desta editora de memória, vamos usar uma subconsulta para nos auxiliar:

UPDATE tbl_livro
SET PrecoLivro = PrecoLivro * 1.12
WHERE IdEditora = 
    (SELECT IdEditora
     FROM tbl_Editora
     WHERE NomeEditora = 'Microsoft Press');

A subconsulta retorna o ID da editora de acordo com o nome da editora fornecido, e este ID é então empregado na consulta principal para aplicar a atualização nos valores dos registros desejados.

4. Subconsulta com operação DELETE

Finalmente, podemos usar subconsultas em instruções DELETE, selecionando o valor a ser excluído de uma tabela de acordo com o retorno da subconsulta.

Sintaxe:

DELETE FROM tabela
WHERE coluna operador (SELECT coluna
                       FROM tabela
                       WHERE coluna operador valor);

Exemplo: Desejamos excluir os livros publicados cujo assunto é “Dinossauros“, porém não sabemos o ID deste assunto na tabela de livros. Suponha também que não sabemos com exatidão se o nome do assunto é “Dinossauros”, “Dinossauro” (no singular), “Dinos” ou algo do gênero – apenas os lembramos que o nome do assunto começa com “Dino”:

DELETE FROM tbl_livro
WHERE IdAssunto =
   (SELECT IdAssunto
    FROM tbl_Assunto
    WHERE NomeAssunto LIKE 'Dino%');

Subconsultas encadeadas

Podemos aninhar uma subconsulta dentro de outra subconsulta, da mesma maneira que uma subconsulta é aninhada dentro de uma consulta principal. Neste caso, a subconsulta mais interna é resolvida primeiro, depois a subconsulta intermediária, e finalmente o resultado é repassado para a consulta principal.

Sintaxe básica:

SELECT coluna(s)
FROM tabela(s)
WHERE coluna operador (SELECT coluna
                       FROM tabela
                       WHERE coluna operador (SELECT coluna
                                              FROM tabela
                                              WHERE coluna operador valor);

Na prática, podemos pensar na subconsulta intermediária como fazendo o papel de uma consulta principal para a subconsulta de nível mais interno, e, assim, o processo é similar para quantos níveis de subconsultas forem aninhados.

Há um limite para a quantidade das subconsultas que podem ser aninhadas? 

Isso depende muito da implementação de banco de dados que está sendo empregada. Por exemplo, o SGBDR Microsoft SQL Server suporta até 32 níveis de aninhamento (subconsulta dentro de subconsulta), porém esse limite pode ser diferente em outros sistemas, muitas vezes por conta de restrições de memória disponível ou da complexidade em si das consultas. Consulte sempre a documentação do sistema em uso para saber mais a respeito.

Confira também o conteúdo deste tutorial em uma aula em vídeo:

Veja também: Cláusula INNER JOIN – Retornar dados de duas ou mais tabelas relacionadas

 

Sobre Fábio dos Reis (1207 Artigos)
Fábio dos Reis trabalha com tecnologias variadas há mais de 30 anos, tendo atuado nos campos de Eletrônica, Telecomunicações, Programação de Computadores e Redes de Dados. É um entusiasta de Ciência e Tecnologia em geral, adora Viagens e Música, e estuda idiomas, além de ministrar cursos e palestras sobre diversas tecnologias em São Paulo e outras cidades do Brasil.

2 Comentários em O que é uma Subconsulta SQL (Subquery)

  1. Wagner Wolmer Massafelli // 14/04/2021 em 22:22 // Responder

    boa noite sr Fábio. fiz o curso de MER e achei fantástico o seu método de ensino. estou tentando fazer agora o VB.net e nao estou conseguindo. como faco para obter as aulas deste curso?
    obrigado
    att Wagner

  2. Parabens pelo video!!!

    Preciso de ajuda em um projeto sobre futebol desde já agradeço, as consultas que preciso são: Total Frequencia + Assiduidade, sendo essa segunda mais complexa, exemplo:

    Cada mês são 4 jogos (relatório é sempre puxado do total de 3 meses ou 90 dias), select abaixo já esta organizado por Total de frequencia, faltando organizar por assiduidade que deve ser comparada sempre a cada frequência anterior.

    Exemplo:
    Dois atletas empatam com 8 frequencias, sendo que o primeiro faltou o último jogo 07/04 e o segundo jogador não, então o segundo jogador fica na frente devido ordem de assiduidade, caso continuem empatados, precisa comparar o penultimo jogo que foi jogo 01/04, e assim por diante até chegar em um jogo que um faltou e esse ficará abaixo na ordem da relação: Total Frequencia + Assiduidade.

    Tabelas resumidas são:

    Jogador
    ncod_jogador
    cnome_joagador

    Frequencias
    ncod_jogador
    nqtdeFrequencia
    dt_Frequencia

    Abaixo o select inicial que falta ordenar por assiduidade:

    select
    frequencias.ncod_jogador,
    jogador.cnome_jogador
    sum(nqtdeFrequencia) as Total_Freq

    from frequencias
    inner join jogador on (frequencias.ncod_jogador = jogador.ncod_jogador)
    where CAST(frequencias.dt_frequencia as date)
    BETWEEN cast( dateadd (day, -90,current_date) as date) and cast(current_date as date)

    Group by
    frequencias.ncod_jogador,
    jogador.cnome_jogador
    Order by Total_Freq DESC;

Escreva um comentário

Seu e-mail não será divulgado


*