Entenda o problema
O que é Subconsultas
SQL é declarativo: você descreve o resultado desejado e o banco decide como buscar. A ordem lógica de execução é FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY.
Cheque seu entendimento
Qual a diferença entre WHERE e HAVING?
Construa o modelo mental
Como pensar antes de fazer
WHERE filtra linhas antes do agrupamento; HAVING filtra grupos depois. Tentar usar uma função de agregação no WHERE é erro clássico.
Não decore a forma. Tente explicar com suas palavras qual problema “Subconsultas” resolve.
Veja funcionando
Exemplo completo, do início ao resultado
INNER JOIN devolve só as correspondências; LEFT JOIN mantém tudo da tabela da esquerda e preenche com NULL. Se um LEFT JOIN 'virou' INNER, quase sempre a culpa é de uma condição sobre a tabela direita colocada no WHERE em vez do ON.
CREATE TABLE cliente (id INTEGER PRIMARY KEY, nome TEXT);
CREATE TABLE pedido (id INTEGER PRIMARY KEY, cliente_id INTEGER, total REAL);
INSERT INTO cliente VALUES (1,'Ana'), (2,'Bruno'), (3,'Carla');
INSERT INTO pedido VALUES (1,1,100.0), (2,1,50.0), (3,2,900.0);
SELECT c.nome, COUNT(p.id) AS pedidos, COALESCE(SUM(p.total), 0) AS gasto
FROM cliente c
LEFT JOIN pedido p ON p.cliente_id = c.id
GROUP BY c.id, c.nome
HAVING COALESCE(SUM(p.total), 0) >= 0
ORDER BY gasto DESC;Leitura linha por linha
CREATE TABLE cliente (id INTEGER PRIMARY KEY, nome TEXT);Contribui para a transformação principal mostrada neste exemplo.
CREATE TABLE pedido (id INTEGER PRIMARY KEY, cliente_id INTEGER, total REAL);Contribui para a transformação principal mostrada neste exemplo.
INSERT INTO cliente VALUES (1,'Ana'), (2,'Bruno'), (3,'Carla');Contribui para a transformação principal mostrada neste exemplo.
INSERT INTO pedido VALUES (1,1,100.0), (2,1,50.0), (3,2,900.0);Contribui para a transformação principal mostrada neste exemplo.
SELECT c.nome, COUNT(p.id) AS pedidos, COALESCE(SUM(p.total), 0) AS gastoDefine uma etapa da consulta e restringe como os dados serão obtidos.
FROM cliente cDefine uma etapa da consulta e restringe como os dados serão obtidos.
LEFT JOIN pedido p ON p.cliente_id = c.idContribui para a transformação principal mostrada neste exemplo.
GROUP BY c.id, c.nomeDefine uma etapa da consulta e restringe como os dados serão obtidos.
Carla não tem pedidos, mas aparece com 0 graças ao LEFT JOIN + COALESCE. HAVING filtra o resultado já agrupado.
Cheque seu entendimento
LEFT JOIN garante que:
Leia por partes
Do detalhe para o todo
Índices tornam a busca rápida em colunas usadas em WHERE e JOIN, ao custo de escrita e espaço. E toda comparação com NULL usa IS NULL — NULL = NULL é desconhecido, não verdadeiro.
Aprenda a diagnosticar
Erros comuns e como corrigi-los
- 1Usar função de agregação no WHERE em vez do HAVING.
- 2Condição da tabela direita no WHERE anulando o LEFT JOIN.
- 3Comparar com = NULL em vez de IS NULL.
Quando algo der errado, compare uma diferença por vez com o exemplo. Evite mudar várias partes ao mesmo tempo.
O que você aprendeu
- SQL é declarativo: você descreve o resultado desejado e o banco decide como buscar. A ordem lógica de execução é FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY.
- Carla não tem pedidos, mas aparece com 0 graças ao LEFT JOIN + COALESCE. HAVING filtra o resultado já agrupado.
- Evite: Usar função de agregação no WHERE em vez do HAVING.
- Evite: Condição da tabela direita no WHERE anulando o LEFT JOIN.
Videoaulas sobre este tema
Se você aprende melhor assistindo, abrimos uma seleção de aulas em vídeo em português sobre exatamente este assunto.
Quiz rápido
0/2 • 0 certas1. Qual a diferença entre WHERE e HAVING?
2. LEFT JOIN garante que: