Boas Práticas de Formatação SQL para Queries Limpas
Todo profissional de bases de dados já herdou uma query que parecia que alguém atirou palavras-chave contra uma parede. Uma formatação SQL adequada transforma blocos de texto ilegíveis em código estruturado e fácil de analisar que qualquer pessoa da sua equipa consegue compreender em segundos. Quer esteja a escrever uma query ad-hoc rápida ou a construir um procedimento armazenado que vai viver em produção durante anos, a forma como formata o seu SQL importa enormemente.
Pode colar qualquer query desorganizada no nosso Formatador SQL e obter uma saída limpa e devidamente indentada instantaneamente — mas compreender porquê certas escolhas de formatação funcionam melhor vai torná-lo num programador SQL mais competente de forma geral.
Porque É Que a Formatação SQL É Importante
SQL mal formatado cria problemas em cascata em todo o seu fluxo de trabalho:
- A depuração demora três vezes mais — Quando uma query devolve resultados errados, precisa de rastrear visualmente a lógica. Uma formatação confusa esconde erros lógicos.
- As revisões de código estagnam — Os revisores passam tempo a decifrar a estrutura em vez de avaliar a lógica.
- Os conflitos de merge multiplicam-se — Uma formatação inconsistente significa que cada membro da equipa reformata de forma diferente, criando diffs desnecessários no git.
- A integração de novos membros sofre — Novos membros da equipa têm dificuldade em compreender a lógica de negócio enterrada em queries emaranhadas.
- Os incidentes de produção escalam — Sob pressão, ninguém quer desemaranhar uma query de 200 linhas sem quebras de linha.
A questão é esta: a formatação SQL não é uma questão de estética. É sobre reduzir a carga cognitiva. Uma query bem formatada comunica a sua intenção antes mesmo de ter lido os nomes das colunas.
Capitalização de Palavras-chave: Escolha uma Convenção e Mantenha-a
O tópico mais debatido na formatação SQL é a capitalização de palavras-chave. Existem três abordagens comuns:
Palavras-chave em MAIÚSCULAS (mais comum):
SELECT
u.first_name,
u.last_name,
o.order_total
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.order_date >= '2025-01-01'
ORDER BY o.order_total DESC;
Palavras-chave em minúsculas:
select
u.first_name,
u.last_name,
o.order_total
from users u
inner join orders o on u.id = o.user_id
where o.order_date >= '2025-01-01'
order by o.order_total desc;
Palavras-chave com Inicial Maiúscula:
Select
u.first_name,
u.last_name,
o.order_total
From users u
Inner Join orders o On u.id = o.user_id
Where o.order_date >= '2025-01-01'
Order By o.order_total Desc;
As palavras-chave em MAIÚSCULAS continuam a ser o padrão da indústria, e com razão. Criam uma separação visual imediata entre as palavras-chave SQL e os nomes das suas tabelas/colunas. Os seus olhos podem percorrer a margem esquerda e compreender instantaneamente a estrutura da query: SELECT, FROM, WHERE, ORDER BY.
Vale a pena notar: qualquer que seja a convenção que escolha, aplique-a com uma ferramenta automatizada. O nosso Formatador SQL trata da capitalização de palavras-chave automaticamente, para que toda a sua equipa se mantenha consistente sem pensar nisso.
Estratégias de Indentação para Cláusulas Principais
Uma boa indentação é a espinha dorsal de SQL legível. Cada cláusula principal deve começar na margem esquerda, e o seu conteúdo deve ser indentado um nível.
Cláusula SELECT
Coloque cada coluna na sua própria linha. Isto torna trivial adicionar, remover ou comentar colunas:
SELECT
e.employee_id,
e.first_name,
e.last_name,
e.department_id,
d.department_name,
e.hire_date,
e.salary
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;
Evite este anti-padrão comum:
-- Difícil de analisar, difícil de modificar
SELECT e.employee_id, e.first_name, e.last_name, e.department_id, d.department_name, e.hire_date, e.salary
FROM employees e INNER JOIN departments d ON e.department_id = d.id;
Cláusulas FROM e JOIN
Cada JOIN fica na sua própria linha. A condição ON fica com o respetivo JOIN, indentada mais se abranger múltiplas condições:
SELECT
o.order_id,
c.customer_name,
p.product_name,
oi.quantity,
oi.unit_price
FROM orders o
INNER JOIN customers c
ON o.customer_id = c.id
INNER JOIN order_items oi
ON o.id = oi.order_id
LEFT JOIN products p
ON oi.product_id = p.id
WHERE o.status = 'completed'
AND o.order_date >= '2025-01-01';
Cláusula WHERE
Cada condição fica na sua própria linha. Coloque o operador booleano (AND/OR) no início de cada nova linha — isto torna muito simples comentar condições individuais durante a depuração:
WHERE o.status = 'completed'
AND o.order_date >= '2025-01-01'
AND o.order_date < '2026-01-01'
AND c.region IN ('US', 'CA', 'UK')
-- AND o.total > 100 (temporariamente desativado)
A boa notícia: assim que interiorizar este padrão, vai detetar erros lógicos muito mais rapidamente. Cada condição está visualmente isolada, por isso filtros em falta ou incorretos saltam imediatamente à vista.
Formatação de JOINs Complexos
As queries do mundo real raramente têm JOINs simples de uma só coluna. Eis como lidar com JOINs de múltiplas condições de forma limpa:
SELECT
s.sale_id,
s.sale_date,
p.product_name,
w.warehouse_name,
i.quantity_on_hand
FROM sales s
INNER JOIN products p
ON s.product_id = p.id
LEFT JOIN inventory i
ON p.id = i.product_id
AND i.warehouse_id = s.warehouse_id
AND i.snapshot_date = s.sale_date
LEFT JOIN warehouses w
ON i.warehouse_id = w.id
WHERE s.sale_date >= '2025-06-01';
Repare como as condições adicionais do JOIN estão indentadas ao mesmo nível da primeira condição ON. Isto torna claro que as três condições pertencem ao mesmo JOIN — e não a uma cláusula WHERE que foi acidentalmente mal colocada.
Para self-joins, utilize aliases descritivos em vez de letras únicas crípticas:
SELECT
mgr.first_name AS manager_name,
emp.first_name AS employee_name,
emp.hire_date
FROM employees emp
INNER JOIN employees mgr
ON emp.manager_id = mgr.employee_id
WHERE mgr.department_id = 10;
Formatação de CTEs (Cláusulas WITH)
As Common Table Expressions merecem atenção especial na formatação porque podem determinar a legibilidade de queries complexas. Cada CTE deve ser tratada como o seu próprio bloco formatado:
WITH monthly_revenue AS (
SELECT
DATE_TRUNC('month', order_date) AS revenue_month,
SUM(order_total) AS total_revenue,
COUNT(DISTINCT customer_id) AS unique_customers
FROM orders
WHERE order_date >= '2025-01-01'
GROUP BY DATE_TRUNC('month', order_date)
),
customer_segments AS (
SELECT
customer_id,
SUM(order_total) AS lifetime_value,
CASE
WHEN SUM(order_total) >= 10000 THEN 'platinum'
WHEN SUM(order_total) >= 5000 THEN 'gold'
WHEN SUM(order_total) >= 1000 THEN 'silver'
ELSE 'bronze'
END AS segment
FROM orders
GROUP BY customer_id
)
SELECT
mr.revenue_month,
mr.total_revenue,
mr.unique_customers,
COUNT(CASE WHEN cs.segment = 'platinum' THEN 1 END) AS platinum_count,
COUNT(CASE WHEN cs.segment = 'gold' THEN 1 END) AS gold_count
FROM monthly_revenue mr
CROSS JOIN customer_segments cs
GROUP BY mr.revenue_month, mr.total_revenue, mr.unique_customers
ORDER BY mr.revenue_month;
Regras-chave de formatação de CTEs:
- Separe as CTEs com uma linha em branco após cada parêntesis de fecho e vírgula
- Indente o corpo de cada CTE como faria com qualquer query normal
- Use nomes descritivos para as CTEs —
monthly_revenueé sempre melhor do quecte1 - Mantenha o SELECT final ao mesmo nível de indentação que a palavra-chave WITH
Formatação de Subqueries
As subqueries devem ser indentadas um nível mais profundo do que a query envolvente. Utilize parêntesis como delimitadores visuais:
SELECT
d.department_name,
d.budget,
dept_stats.avg_salary,
dept_stats.employee_count
FROM departments d
INNER JOIN (
SELECT
department_id,
AVG(salary) AS avg_salary,
COUNT(*) AS employee_count
FROM employees
WHERE status = 'active'
GROUP BY department_id
HAVING COUNT(*) >= 5
) dept_stats
ON d.id = dept_stats.department_id
WHERE d.budget > 100000
ORDER BY dept_stats.avg_salary DESC;
Quando tem subqueries aninhadas a três ou quatro níveis de profundidade, isso é normalmente um sinal para refatorizar em CTEs. As CTEs aplanam o aninhamento e dão a cada passo lógico um nome legível. O nosso Formatador SQL pode ajudá-lo a identificar estruturas profundamente aninhadas que podem beneficiar de refatorização.
Formatação de Instruções CASE
As instruções CASE aparecem em todo o lado — em listas SELECT, cláusulas WHERE, ORDER BY e até em condições de JOIN. Mantenha-as legíveis com indentação consistente:
SELECT
order_id,
order_total,
CASE
WHEN order_total >= 1000 THEN 'high-value'
WHEN order_total >= 100 THEN 'medium-value'
ELSE 'low-value'
END AS order_tier,
CASE status
WHEN 'shipped' THEN 'In Transit'
WHEN 'delivered' THEN 'Complete'
WHEN 'returned' THEN 'Refund Pending'
ELSE 'Processing'
END AS display_status
FROM orders;
As palavras-chave WHEN e ELSE alinham-se entre si, e a palavra-chave END alinha-se com CASE. Isto cria um bloco visual limpo que é fácil de analisar e modificar.
Boas Práticas de Comentários em SQL
Os comentários em SQL são os melhores amigos do seu eu futuro. Utilize-os estrategicamente:
Comentários de bloco para o propósito da query:
/*
* Relatório Mensal de Receita
* Gera a desagregação de receita por categoria de produto
* Utilizado por: Dashboard financeiro (Tableau)
* Última modificação: 2025-06-15
*/
SELECT
pc.category_name,
SUM(oi.quantity * oi.unit_price) AS revenue
FROM order_items oi
INNER JOIN products p ON oi.product_id = p.id
INNER JOIN product_categories pc ON p.category_id = pc.id
GROUP BY pc.category_name;
Comentários inline para lógica não óbvia:
WHERE o.order_date >= '2025-01-01'
AND o.status != 'cancelled'
AND o.payment_verified = TRUE -- exclui revisões de pagamento pendentes
AND c.account_type != 'internal' -- encomendas de teste do staff usam contas internas
Comentários de secção para queries longas:
-- === Cálculo de Receita ===
...
-- === Filtragem de Clientes ===
...
-- === Agregação Final ===
Evite comentar em excesso coisas óbvias. -- selecionar todas as colunas acima de uma instrução SELECT adiciona ruído, não clareza.
Formatação para Diferentes Dialetos SQL
Os dialetos SQL têm as suas próprias particularidades de sintaxe, mas os princípios de formatação mantêm-se consistentes. Eis considerações específicas por dialeto:
MySQL
SELECT
product_name,
price,
IFNULL(discount, 0) AS discount,
price - IFNULL(discount, 0) AS final_price
FROM products
WHERE category_id IN (1, 3, 5)
LIMIT 50 OFFSET 100;
PostgreSQL
SELECT
product_name,
price,
COALESCE(discount, 0) AS discount,
price - COALESCE(discount, 0) AS final_price
FROM products
WHERE category_id = ANY(ARRAY[1, 3, 5])
LIMIT 50 OFFSET 100;
SQL Server
SELECT TOP 50
product_name,
price,
ISNULL(discount, 0) AS discount,
price - ISNULL(discount, 0) AS final_price
FROM products
WHERE category_id IN (1, 3, 5)
ORDER BY price DESC
OFFSET 100 ROWS FETCH NEXT 50 ROWS ONLY;
Independentemente do dialeto, a formatação estrutural mantém-se a mesma: palavras-chave nas suas próprias linhas, indentação consistente, uma coluna por linha. O Formatador SQL no alltools.one suporta todos os principais dialetos, para que obtenha resultados consistentes independentemente da base de dados com que esteja a trabalhar.
Formatação Automatizada vs. Formatação Manual
A formatação manual funciona bem para queries curtas. Mas assim que a sua equipa cresce além de duas pessoas, precisa de aplicação automatizada. Eis porquê:
Benefícios da formatação automatizada:
- Zero debates — O formatador decide, todos seguem
- Diffs de git consistentes — Sem mais alterações apenas de espaços em branco a poluir os pull requests
- Velocidade — Reformatar um procedimento armazenado de 500 linhas à mão demora minutos. Uma ferramenta fá-lo em milissegundos.
- Integração — Novos membros da equipa não precisam de memorizar guias de estilo
Quando a formatação manual ainda ganha:
- Alinhamento de colunas específicas em instruções INSERT ou blocos CASE complexos
- Preservar formatação intencional em queries de documentação
- Casos extremos onde ferramentas automatizadas comprometem a legibilidade (raro, mas acontece)
A abordagem pragmática: use a formatação automatizada como base, depois ajuste manualmente as poucas queries onde isso importa. Passe o seu SQL pelo nosso Formatador SQL primeiro, depois ajuste secções específicas se necessário.
Referência Rápida: Checklist de Formatação SQL
Antes de fazer commit de qualquer SQL no seu código, passe por esta checklist:
- As palavras-chave têm capitalização consistente (preferencialmente MAIÚSCULAS)
- Cada cláusula principal (SELECT, FROM, WHERE, GROUP BY, ORDER BY) começa numa nova linha
- As colunas no SELECT estão uma por linha
- Os JOINs estão cada um na sua própria linha com condições ON indentadas
- As condições WHERE estão uma por linha com AND/OR no início
- As CTEs têm nomes descritivos e indentação consistente
- As instruções CASE têm WHEN/ELSE alinhados
- Os comentários explicam o porquê, não o quê
- Os aliases de tabelas são descritivos (não apenas letras únicas para queries complexas)
- Subqueries com mais de dois níveis de profundidade foram refatorizadas em CTEs
Recursos Relacionados
Se está a trabalhar na qualidade geral do código, estes guias complementam bem a formatação SQL:
- Boas Práticas de Formatação JSON — Princípios de formatação semelhantes para estruturas de dados JSON
- Guia de Comparação de Diferenças de Texto — Útil para rever alterações de formatação em ficheiros SQL
- Folha de Referência de Regex — Prático para escrever correspondência de padrões SQL com LIKE e SIMILAR TO
A formatação limpa de SQL é uma daquelas práticas que quase não custa nada a adotar mas que rende dividendos todos os dias. O seu eu futuro — e cada colega que tocar nas suas queries — vai agradecer-lhe.
🛠️ Experimente agora: Formatador SQL — Formate e embeleze queries SQL instantaneamente. 100% gratuito, processa tudo no seu navegador. Sem envio de dados.