Do básico ao avançado, com exemplos reais e explicações absurdamente claras.
Este post não foi escrito por uma IA que copia a W3Schools. Foi escrito como se fosse pra salvar seu banco de dados em produção. E talvez seja.
1. SELECT, WHERE, ORDER BY, LIMIT – A base de tudo
SELECT nome, email
FROM usuarios
WHERE ativo = 'sim'
ORDER BY criado_em DESC
LIMIT 10;
SELECT: define quais colunas você quer ver.
FROM: diz de onde esses dados vão sair.
WHERE: filtra os resultados. Aqui é onde você separa os vivos dos zumbis do sistema.
ORDER BY: ordena os dados. Pode ser ASC ou DESC.
LIMIT: limita quantas linhas vão aparecer.
2. Filtros Avançados – Refinando sua busca sem perder a dignidade
BETWEEN – Intervalos com classe
SELECT * FROM usuarios
WHERE idade BETWEEN 18 AND 30;
Pega todo mundo entre 18 e 30, inclusive os dois extremos.
LIKE – Busca textual com padrão
SELECT * FROM produtos
WHERE nome LIKE '%café%';
% é o coringa. Começa com, termina com, ou contém. Serve pra buscar coisas imprevistas (tipo o nome do estagiário).
IS NULL / IS NOT NULL – Porque NULL não é nada, mas também é tudo
SELECT * FROM pedidos
WHERE data_entrega IS NULL;
NULL é a ausência de valor. Comparar com = não funciona. Use IS NULL ou IS NOT NULL.
IN / NOT IN – Filtros que evitam drama
SELECT * FROM clientes
WHERE cidade IN ('Curitiba', 'São Paulo', 'Florianópolis');
Mais limpo do que vários OR cidade = ....
Troque por NOT IN se quiser excluir.
3. JOINs – Como unir tabelas com elegância
SELECT u.nome, p.valor
FROM usuarios u
JOIN pedidos p ON u.id = p.usuario_id;
INNER JOIN: traz apenas os que combinam nas duas tabelas.
LEFT JOIN: traz todos da esquerda, mesmo que não tenham correspondência.
RIGHT JOIN: o inverso.
FULL JOIN: todos de todos os lados (quando o banco suporta).
Exemplo com LEFT JOIN:
SELECT u.nome, p.valor
FROM usuarios u
LEFT JOIN pedidos p ON u.id = p.usuario_id;
Isso inclui quem nunca fez um pedido também.
4. GROUP BY, HAVING e Funções Agregadas
SELECT categoria, COUNT(*)
FROM produtos
GROUP BY categoria
HAVING COUNT(*) > 5;
GROUP BY agrupa os resultados por coluna.
HAVING é como um WHERE, mas é aplicado depois da agregação.
Funções comuns: COUNT(), SUM(), AVG(), MIN(), MAX()
5. Subqueries e CTEs – A mente dentro da mente
Subquery
SELECT nome
FROM usuarios
WHERE id IN (
SELECT usuario_id FROM pedidos WHERE valor > 100
);
CTE (Common Table Expression)
WITH top_usuarios AS (
SELECT usuario_id, COUNT(*) as total
FROM pedidos
GROUP BY usuario_id
)
SELECT * FROM top_usuarios
WHERE total > 10;
Subqueries são úteis, mas podem ficar ilegíveis. CTEs deixam o código mais limpo e reutilizável.
6. Funções de Janela (Window Functions) – Zoom nos dados
SELECT nome,
RANK() OVER(PARTITION BY cidade ORDER BY idade DESC) as ranking
FROM usuarios;
As window functions permitem calcular valores sobre um grupo sem colapsar as linhas (como o GROUP BY faz).
Outras funções: ROW_NUMBER(), DENSE_RANK(), LAG(), LEAD()
7. Performance e Boas Práticas
- Use
EXPLAINpra entender como a query roda - Crie índices para colunas usadas em
WHERE,JOINeORDER BY - Evite
SELECT *em ambientes críticos - Prefira
INem vez de váriosOR - Nunca compare
NULLcom=
8. Erros Comuns e Pegadinhas
- Usar
=comNULL(não funciona) - Esquecer o
GROUP BYao usar função agregada - Misturar tipos de dados sem conversão
LIMITsemORDER BY→ resultados aleatórios- Subquery que retorna mais de uma linha onde só uma era esperada
9. Ferramentas de Teste
- DB Fiddle: https://www.db-fiddle.com/
- SQL Playground (W3Schools): https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
- DBeaver (Desktop): https://dbeaver.io/
Post produzido com café, testes reais e zero paciência pra query lenta
