Voltar para a lista de artigos Artigos
9 minutos de leitura

Guia para iniciantes na Subconsulta SQL

As subconsultas são um poderoso recurso SQL, permitindo-nos combinar dados de várias tabelas em uma única consulta. Neste artigo, vamos lhe ensinar tudo o que você precisa para começar a usar as subconsultas.

Talvez a definição mais simples de uma subconsulta SQL seja "Uma consulta dentro de uma consulta". As subconsultas são tão fáceis de entender que freqüentemente aparecem nos capítulos de abertura dos cursos SQL.

Entretanto, há muitas variantes de subconsultas que precisam ser explicadas. E embora as subconsultas sejam geralmente usadas na cláusula WHERE, você pode usá-las em outras cláusulas, tais como FROM, HAVING, e SELECT.

Em resumo, há muito mais a saber sobre subconsultas do que apenas o que elas são e para onde vão. Então, vamos começar com nosso primeiro exemplo de uma subconsulta SQL para iniciantes.

Subconsultas básicas por exemplo

Antes de entrarmos em subconsultas, precisamos explicar nossas tabelas de banco de dados. Para relaxar nossa mente nesta época de distanciamento social, vou usar exemplos relacionados a lugares bonitos e relaxantes. Nosso banco de dados de amostras terá duas tabelas. A primeira tabela é chamada best_10_places e armazena os 10 melhores lugares para diferentes tipos de atividades (como snorkeling, esqui e trekking). A tabela tem colunas para o nome do lugar, a atividade que podemos fazer ali, o ranking deste lugar, e a cidade mais próxima. Dê uma olhada:

Place_NameActivityRanking_PositionClosest_City
Praia do Sepulturasnorkeling1Florianopolis
Hanauma Baysnorkeling2Honolulu
Elliot Islandsnorkeling3Melbourne
Cerro Catedralskiing1Bariloche
Camino de Santiagotrekking1Compostela
Cerro Ottotrekking2Bariloche
Black Vulcanotrekking3Honolulu

Tabela: best_10_places


Se você quiser viajar para qualquer um destes belos lugares, você precisará de uma passagem; o one_way_ticket A tabela tem um registro para qualquer par de cidades que estejam conectadas por qualquer tipo de transporte. Usaremos esta tabela para determinar como ir de uma cidade para outra. As colunas contêm informações sobre a cidade de origem, cidade de destino, preço do bilhete, tempo de viagem e tipo de transporte (por exemplo, ferroviário, aéreo, etc.). Abaixo está um subconjunto desta tabela:

City_OriginCity_DestinationTicket_PriceTravel_TimeTransportation
ParisFlorianopolis830.0011hr 30 minair
ParisHonolulu1564.0015hr 20 minair
ParisMelbourne2200.0018hr 50minair
ParisBariloche970.0012hr 20 minair
MadridCompostela80.001hr 10minair

Tabela: bilhete_de_uma_via


Agora estamos prontos para o primeiro exemplo. Vamos supor que uma pessoa em Paris queira ir para o primeiro lugar do mundo para fazer snorkeling. Que tipo de transporte vai de Paris para este lugar?

Como você provavelmente sabe, a consulta SQL mais simples é formada por uma SELECT, uma FROM, e (opcionalmente) uma cláusula WHERE. E como mencionamos anteriormente, uma subconsulta é uma consulta dentro de uma consulta. Assim, no próximo exemplo você verá duas consultas: a consulta principal (também chamada de consulta externa) e a subconsulta(em azul):

SELECT city_destination, transportation, ticket_price, travel_time
FROM one_way_ticket
WHERE city_destination = (
    SELECT closest_city
    FROM best_10_places
    WHERE activity_type = 'snorkeling'
      AND ranking_position = 1
  )
  AND city_origin = 'Paris'

A subconsulta é executada primeiro, devolvendo o closest_city ao melhor destino de snorkeling (a cidade de Florianópolis no Brasil). Em seguida, a consulta principal é executada, substituindo a subquisição pelo seu resultado (Florianópolis). O resultado final é:

City_DestinationTransportationTicket_PriceTravel_Time
Florianopolisair$ 830.0011hr 30 min

Ao utilizar as subconsultas:

  • A subconsulta deve ser sempre entre parênteses.
  • Preste atenção ao operador utilizado para comparar o resultado da subconsulta. Em nosso exemplo anterior, usamos "="; entretanto, este operador deve ser usado com subconsultas que retornam apenas uma linha e apenas uma coluna (também conhecidas como subconsultas "escalares").

Sugiro que você leia o artigo SQL Subqueries para ver mais exemplos de subconsultas para iniciantes explicados em detaiI. As subconsultas também fazem parte de nosso SQL para Iniciantes curso, um tutorial passo-a-passo que o leva através de SQL fundacional usando exemplos e exercícios.

Subconsultas escalares ou não escalares: Essa é a questão

Assim, uma subconsulta escalar retorna apenas uma coluna com apenas uma fila. O que é uma subconsulta não escalar? Uma subconsulta que retorna várias fileiras.

Há muitos operadores que podemos usar para comparar uma coluna com uma subconsulta. Entretanto, alguns deles só podem ser usados com subconsultas escalares: =, >, >=, < e <=. Se você usar um destes operadores, sua subconsulta deve ser escalar.

Vejamos um exemplo com uma subconsulta escalar. Suponha que você tenha um cliente que queira ir de Paris para Bariloche. Antes de comprar o bilhete, o cliente quer ver se há algum lugar com um bilhete mais barato. A consulta abaixo encontrará essas cidades:

SELECT city_destination, ticket_price, travel_time, transportation
FROM one_way_ticket
WHERE ticket_price < (
    SELECT ticket_price
    FROM one_way_ticket
    WHERE city_destination = 'Bariloche'
      AND city_origin = 'Paris'
  )
  AND city_origin = 'Paris'

Novamente, a subconsulta é executada primeiro; seu resultado (o preço de um bilhete Paris-Bariloche, ou $970) é comparado com a coluna ticket_price na consulta externa. Isto obtém todos os registros em one_way_ticket com um valor ticket_price inferior a $970. O resultado da consulta é mostrado abaixo:

City_DestinationTicket_PriceTravel_TimeTransportation
Florianopolis830.0011hr 30 minair
Compostela80.001hr 10minair

Outros operadores, como IN, EXISTS ou NOT EXISTS, > ALL, = ANY, podem ser usados com subconsultas escalares ou não escalares.

Nosso próximo exemplo utiliza o operador IN. Vamos supor que a pessoa que perguntou sobre o melhor lugar para snorkeling queira explorar outros destinos; de fato, ela gostaria de ver os três melhores lugares para snorkeling. A mudança em nossa subconsulta é clara: só precisamos mudar “ranking_position = 1” com “ranking_position <= 3”. Entretanto, nossa subconsulta retornará três registros e não será mais escalar. Vamos usar o operador IN, assim:

SELECT city_destination, transportation, ticket_price, travel_time
FROM one_way_ticket
WHERE city_destination IN (
    SELECT closest_city
    FROM best_10_places
    WHERE activity_type = 'snorkeling'
      AND ranking_position <= 3
  )
  AND city_origin = 'Paris'

Como no exemplo anterior, o banco de dados executa primeiro a subquisição, que retorna uma lista de três cidades (as cidades mais próximas aos 3 principais destinos de snorkeling: Florianópolis, Honolulu, e Melbourne). Em seguida, a consulta externa é executada com estas condições:

city_destination IN ('Florianopolis', 'Honolulu', 'Melbourne')

O operador IN retorna TRUE quando o valor de city_destination é uma destas três cidades. Assim, a consulta principal retorna o seguinte resultado:

City_DestinationTransportationTicket_PriceTravel_Time
Florianopolisair$ 830.0011hr 30 min
Honoluluair$ 1564.0015hr 20 min
Melbourneair$ 2200.0018hr 50min

Se você quiser ir mais fundo nas nuances das subconsultas SQL, confira o capítulo de subconsultas de nossa SQL para Iniciantes curso, onde você pode encontrar vários exemplos e muitos exercícios práticos.

Subconsultas avançadas

O conceito de subquisição é fácil de entender. Mas devido à flexibilidade do SQL, as subconsultas podem ser usadas de muitas formas diferentes. Cobrir todas as utilizações possíveis está além do escopo deste artigo. O que faremos ao invés disso é demonstrar alguns dos usos mais importantes.

Quantos lugares diferentes você pode colocar uma subconsulta?

Subconsultas podem ser usadas em diferentes lugares em uma consulta SQL, incluindo as cláusulas WHERE, FROM, HAVING, e SELECT; além disso, uma subconsulta também pode ser usada como parte de uma declaração UPDATE, DELETE, ou INSERT. No próximo exemplo, veremos como usar uma subconsulta na cláusula FROM.

Suponha que o proprietário da agência de viagens queira mostrar cada cidade junto com o custo do bilhete e o número de "melhores lugares" próximos a esta cidade. Para obter a quantidade de "melhores lugares" para cada cidade, usaremos uma subconsulta (mostrada em azul) na cláusula FROM para criar uma pseudo tabela. Em seguida, a consulta externa será JOIN com one_way_ticket e a pseudo-mesa.

SELECT city_destination, ticket_price, pseudo_table.quantity
FROM one_way_ticket
JOIN (
    SELECT closest_city AS city, count(*) AS quantity
    FROM best_10_places
    GROUP BY 1
  ) pseudo_table
  ON one_way_ticket.pseudo_table.city

O resultado desta consulta é:

City_DestinationTicket_PriceQuantity
Florianopolis830.001
Honolulu1564.002
Melbourne2200.001
Bariloche970.002
Compostela80.001

Para saber mais sobre o uso de subconsultas em outras instruções SQL, leia Subconsultas em instruções UPDATE e DELETE. Este artigo tem vários exemplos com código SQL que está pronto para copiar e colar se você quiser experimentá-lo.

EXISTÊNCIAS: Um operador orientado a subconsultas

Um dos operadores mais poderosos que você pode usar com subconsultas é o operador EXISTS. Como podemos ver no exemplo abaixo, o operador EXISTS deve vir antes da subconsulta. Ele retornará TRUE se a subconsulta retornar pelo menos uma fila - não importa qual seja o conteúdo da fila. Se a subconsulta retornar 0 fileiras, EXISTS retornará FALSE.

Para o próximo exemplo, vamos supor que nosso cliente de Paris queira viajar para um lugar onde possa fazer tanto trekking quanto snorkeling. A consulta abaixo pode ser usada para responder a este cliente:

SELECT city_destination, transportation, ticket_price, travel_time
FROM one_way_ticket
WHERE EXISTS (
    SELECT closest_city
    FROM best_10_places
    WHERE activity_type = 'snorkeling'
      AND closest_city = one_way_ticket.city_destination
  )
  AND EXISTS (
    SELECT closest_city
    FROM best_10_places
    WHERE activity_type = 'trekking'
    AND closest_city = one_way_ticket.city_destination
  )
  AND city_origin = 'Paris'

O resultado mostra os registros relacionados às cidades com atividades de trekking e snorkeling:

City_DestinationTransportationTicket_PriceTravel_Time
Honoluluair$ 1564.0015hr 20 min

Um ponto interessante na subconsulta anterior é a referência à coluna one_way_ticket.city_destination na consulta externa. As subconsultas que fazem referência às colunas na consulta externa são chamadas de "subconsultas correlatas" e têm alguns comportamentos específicos. Como no exemplo anterior, as subconsultas correlacionadas tendem a ser usadas com os operadores das subconsultas EXISTS e NOT EXISTS.

As subconsultas correlacionadas são um poderoso recurso SQL. Em certos cenários, elas são a forma natural de resolver um problema. Se você estiver interessado neste tópico, sugiro a leitura de Subconsultas Correlatas em SQL: Um Guia para Iniciantes e Aprenda a Escrever uma Subconsulta Relacionada a SQL em 5 minutos.

Os operadores ALL e ANY

Este par de operadores funciona em conjunto com os operadores =, <>, >, >=, < e <=, acrescentando mais expressividade ao idioma. Devido ao alto número de combinações possíveis com TODOS e QUALQUER, incluí uma tabela com os usos mais comuns destes operadores:

ConditionReturns TRUE if ...Returns FALSE if ...
Where 10 > ANY ( subquery )The subquery returns at least one value that’s greater than 10.All returned values are 10 or less.
Where 10 > ALL ( subquery )The subquery returns only values greater than 10.The subquery returns at least one value of 10 or less.
Where 10 = ANY (subquery)The subquery returns at least one value equal to 10.No returned values are equal to 10.
Where 10 = ALL (subquery)All values returned by subquery are 10.At least one returned value is not equal to 10.

Vamos aplicar este operador a um exemplo da vida real. Suponhamos que queremos promover todos os "melhores lugares do mundo" que você pode visitar com um bilhete inferior a US$1.000. Cada "melhor lugar" da mesa best_10_places pode ter muitos bilhetes possíveis; estamos interessados apenas naqueles lugares onde pelo menos um bilhete custa menos de US$ 1000. A consulta é a seguinte:

SELECT Place_name, Activity, Ranking_position
FROM best_10_places
WHERE 1000 > ANY (
    SELECT ticket_price
    FROM one_way_ticket
    WHERE city_destination = best_10_places.closest_city
  )

Os resultados da consulta anterior são mostrados abaixo. Você pode ir para o melhor lugar para qualquer atividade (snorkeling, esqui e trekking) por menos de US$1.000!

Place_NameActivityRanking_Position
Praia do Sepulturasnorkeling1
Cerro Catedralskiing1
Camino de Santiagotrekking1
Cerro Ottotrekking2

Seus Próximos Passos com Subconsultas

Neste artigo, eu expliquei as subconsultas e mostrei vários exemplos de como utilizá-las. Ainda assim, este tópico tem muitas variações, incluindo os diferentes tipos de subconsultas e operadores. Para ter uma compreensão mais completa das subconsultas, sugiro fazer um curso online como o LearnSQL.com.br's SQL para Iniciantes ou lendo os artigos adicionais que mencionei.