Subconsultas e Conjuntos
Subqueries no SELECT/FROM/WHERE, UNION, INTERSECT e EXCEPT
Subqueries (subconsultas) são queries dentro de queries. Podem aparecer no SELECT (subquery escalar), no FROM (derived table ou subquery lateral) ou no WHERE/HAVING (filtros correlacionados ou não).
UNION combina resultados de duas queries com as mesmas colunas, eliminando duplicatas. UNION ALL é mais rápido pois não deduplica. INTERSECT retorna apenas linhas presentes em ambas as queries. EXCEPT retorna linhas da primeira que não existem na segunda.
CTEs (Common Table Expressions) com WITH tornam queries complexas mais legíveis ao nomearem subqueries, podendo ser reutilizadas múltiplas vezes na mesma query.
-- Subquery no WHERE
SELECT nome FROM clientes
WHERE id IN (
SELECT DISTINCT cliente_id
FROM pedidos
WHERE valor > 1000
);
-- Subquery escalar no SELECT
SELECT
nome,
(SELECT COUNT(*) FROM pedidos p WHERE p.cliente_id = c.id) AS total_pedidos
FROM clientes c;
-- Derived table no FROM
SELECT depto, media
FROM (
SELECT departamento AS depto, AVG(salario) AS media
FROM funcionarios
GROUP BY departamento
) AS medias_departamento
WHERE media > 8000;
-- CTE — muito mais legível
WITH clientes_vip AS (
SELECT cliente_id, SUM(valor) AS gasto_total
FROM pedidos
GROUP BY cliente_id
HAVING SUM(valor) > 10000
),
info_completa AS (
SELECT c.nome, cv.gasto_total
FROM clientes c
JOIN clientes_vip cv ON c.id = cv.cliente_id
)
SELECT * FROM info_completa ORDER BY gasto_total DESC;
-- UNION
SELECT nome FROM clientes_br
UNION
SELECT nome FROM clientes_us; -- sem duplicatas
-- UNION ALL (mais rápido)
SELECT 'Receita' AS tipo, SUM(valor) AS total FROM vendas
UNION ALL
SELECT 'Custo', SUM(valor) FROM compras;Prefira CTEs (WITH) a subqueries aninhadas — são muito mais legíveis e algumas databases as otimizam melhor.