Pular para o conteúdo

SQL legível — um guia de estilo prático para formatar consultas

Como organizar SELECT, JOIN, WHERE e CTEs para a consulta ficar fácil de ler e revisar, por que o dialeto importa ao formatar e os hábitos que evitam bugs.

Por Felipe YamaokaPublicado em 5 de novembro de 20265 min de leitura

A consulta de uma linha no log

Mais cedo ou mais tarde você precisa depurar uma consulta assim, copiada do log do ORM ou de uma ferramenta de monitoramento:

sql
select u.id, u.name, count(o.id) as orders from users u left join orders o on o.user_id = u.id where u.active = 1 and o.created_at >= '2026-01-01' group by u.id, u.name having count(o.id) > 5 order by orders desc limit 10

Funciona, mas ler exige ir e voltar para achar onde termina a condição do join e onde começa o filtro. A mesma consulta, formatada:

sql
SELECT
  u.id,
  u.name,
  count(o.id) AS orders
FROM
  users u
  LEFT JOIN orders o ON o.user_id = u.id
WHERE
  u.active = 1
  AND o.created_at >= '2026-01-01'
GROUP BY
  u.id,
  u.name
HAVING
  count(o.id) > 5
ORDER BY
  orders DESC
LIMIT
  10

Agora cada cláusula tem o seu bloco e cada condição a sua linha. Dá para ver de relance que o filtro em o.created_at está no WHERE, o que transforma o LEFT JOIN num inner join sem ninguém perceber: usuários sem pedidos recentes somem do resultado. Esse tipo de bug se esconde no SQL de uma linha e salta aos olhos no SQL formatado. Este guia cobre as convenções que tornam isso possível.

Formatar muda o layout, não o significado

Um formatador só mexe em espaços, quebras de linha e, se você pedir, na caixa das palavras-chave. Os tokens e a ordem deles continuam iguais, então a consulta formatada devolve exatamente o mesmo resultado. Por isso é seguro formatar qualquer consulta, inclusive uma que você ainda não entendeu direito, e o diff da revisão de código passa a mostrar lógica, e não espaçamento.

As convenções que mais importam

Não existe um estilo oficial de SQL, mas a maioria dos guias concorda em algumas regras:

  1. Uma cláusula por bloco. SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY e LIMIT começam na margem esquerda, e o conteúdo vem indentado embaixo.
  2. Uma coluna por linha no SELECT. Acrescentar, tirar ou comentar uma coluna vira uma mudança de uma linha, e o diff fica pequeno.
  3. Uma condição por linha, com o operador na frente. Começar as linhas com AND e OR deixa a lógica visível e fácil de comentar.
  4. Join com a condição na mesma linha. LEFT JOIN orders o ON o.user_id = u.id mantém cada relacionamento legível como uma unidade.
  5. Caixa consistente nas palavras-chave. Palavras-chave em maiúsculas (SELECT, FROM) são a convenção mais comum, porque separam a linguagem dos nomes de tabelas e colunas. Minúsculas também funcionam; o que atrapalha é misturar.
  6. Aliases com significado. u para users e o para orders funcionam numa consulta curta. Numa longa, clientes c e notas_fiscais nf são melhores que t1 e t2.

O tamanho da indentação é questão de gosto: dois espaços, quatro ou tab, desde que o projeto inteiro use o mesmo.

Subconsultas e CTEs

Subconsultas aninhadas são onde a legibilidade costuma desmoronar. Uma CTE (common table expression), introduzida com WITH, permite dar nome a um resultado intermediário e ler a consulta de cima para baixo:

sql
WITH
  recent AS (
    SELECT
      user_id,
      sum(total) AS spent
    FROM
      orders
    WHERE
      created_at >= '2026-01-01'
    GROUP BY
      user_id
  )
SELECT
  u.name,
  r.spent
FROM
  users u
  JOIN recent r ON r.user_id = u.id
WHERE
  r.spent > 1000
ORDER BY
  r.spent DESC

Cada CTE é indentada como uma consulta própria. Um bom nome, como recent aqui, documenta o que a etapa faz melhor do que um comentário.

Por que o dialeto importa

SQL parece igual em todo lugar até deixar de parecer. Cada banco tem a sua sintaxe para citar identificadores, para parâmetros e para algumas funções, e o formatador precisa saber qual você usa para ler a consulta direito:

  • SQL Server cita identificadores com colchetes: [dbo].[users].
  • MySQL envolve os identificadores em crases, o mesmo caractere usado para código no Markdown.
  • PostgreSQL usa aspas duplas para identificadores e $1, $2 para parâmetros.
  • SQLite aceita vários estilos, por compatibilidade.

Passe select [id] from [dbo].[users] para um formatador configurado como SQL padrão e ele falha no primeiro colchete; configure como SQL Server (T-SQL) e ele formata sem problema. O Formatador SQL deste site aceita SQL padrão, PostgreSQL, MySQL, SQL Server e SQLite, e quando não consegue ler a consulta mostra a linha e a coluna do problema, como uma aspa sem fechamento em where name = 'Ana.

Hábitos que evitam bugs

Formatar é sobre leitura, mas alguns hábitos de escrita andam junto:

  • Liste as colunas em vez de SELECT * no código da aplicação. Uma coluna nova na tabela não deveria mudar, sem ninguém ver, o que o seu código recebe.
  • Qualifique as colunas com o alias da tabela em qualquer consulta com join. o.created_at não fica ambíguo quando alguém acrescenta um created_at em outra tabela.
  • Coloque condição de join no ON e filtro no WHERE, e pense duas vezes quando uma condição do WHERE usa o lado opcional de um LEFT JOIN, como no exemplo do começo.
  • Use parâmetros, nunca concatenação de texto, para valores que vêm do usuário. Isso evita SQL injection e deixa o banco reaproveitar planos de execução.
  • Escreva ORDER BY sempre que a ordem importar. Sem ele, o banco pode devolver as linhas em qualquer ordem, e essa ordem pode mudar.

Formatação no fluxo do time

Combinar um estilo é mais fácil quando ninguém precisa cobrar na mão. Guarde as consultas em arquivos .sql, rode um formatador antes do commit e revise a versão formatada. Para conferências rápidas, como uma consulta colada de um log ou da mensagem de um colega, um formatador online que roda no navegador resolve, desde que a consulta não saia da sua máquina. Consultas podem ter nomes de tabelas, dados de clientes em literais, como CPF e e-mail, e a estrutura interna do sistema, então evite ferramentas que fazem upload delas.

Erros comuns

  • Revisar consultas longas de uma linha sem formatar antes.
  • Misturar palavras-chave em maiúsculas e minúsculas no mesmo código.
  • Formatar com o dialeto errado e "corrigir" erros que não existem.
  • Usar SELECT * no código da aplicação.
  • Filtrar sem querer o lado opcional de um LEFT JOIN no WHERE.
  • Montar consultas concatenando entrada do usuário.

Resumo

SQL legível coloca cada cláusula no seu bloco, cada coluna e cada condição na sua linha e as palavras-chave numa caixa consistente. Formatar nunca muda o que a consulta faz, então formate à vontade, mas escolha o dialeto certo para o formatador entender os seus identificadores e parâmetros. Somado a colunas explícitas, nomes qualificados e parâmetros, isso transforma consultas em código fácil de revisar.

Leia também