Capa do Ebook gratuito SQL para Análise de Dados no Dia a Dia: Consultas, Relatórios e Insights com Dados Reais

SQL para Análise de Dados no Dia a Dia: Consultas, Relatórios e Insights com Dados Reais

Novo curso

26 páginas

Boas práticas de legibilidade: alias, formatação, nomes e estrutura de query

Capítulo 19

Tempo estimado de leitura: 0 minutos

+ Exercício

Legibilidade em SQL é a capacidade de outra pessoa (ou você mesmo daqui a algumas semanas) entender rapidamente o que a query faz, quais regras de negócio ela aplica e onde ajustar algo sem quebrar o resultado. Em análises do dia a dia, legibilidade não é “estética”: ela reduz erros, facilita revisão por pares, acelera manutenção e diminui o risco de interpretações erradas em relatórios. Boas práticas de legibilidade se apoiam em quatro pilares: alias consistentes, formatação previsível, nomes claros e estrutura de query em blocos.

Princípios de legibilidade que guiam todas as decisões

1) “Leitura em blocos” antes de “leitura linha a linha”

Uma query legível permite que alguém entenda o objetivo olhando primeiro para a estrutura: quais tabelas entram, quais filtros são aplicados, como os campos são calculados e como o resultado é organizado. Isso pede blocos bem separados (SELECT, FROM/JOIN, WHERE, GROUP BY, HAVING, QUALIFY/ORDER BY) e uma ordem consistente de colunas e condições.

2) Consistência é mais importante do que preferência pessoal

Não existe um único estilo “correto”, mas existe estilo inconsistente. Se você escolhe usar palavras-chave em maiúsculas, mantenha em maiúsculas. Se você escolhe prefixar alias com abreviações, mantenha o padrão. Consistência reduz esforço cognitivo.

3) Evite “surpresas” e “mágica”

Legibilidade também é previsibilidade. Evite abreviações obscuras, números mágicos sem contexto, colunas com nomes ambíguos e cálculos escondidos em expressões gigantes. Prefira decompor em etapas e nomear cada etapa de forma descritiva.

Boas práticas de alias: clareza e economia sem perder contexto

Alias de tabela: curtos, estáveis e sem ambiguidade

Alias de tabela devem reduzir repetição sem virar criptografia. Um padrão comum é usar 1 a 3 letras que remetem ao nome da tabela, evitando colisões. Exemplo: orders vira o ou ord, customers vira c ou cus. Em queries com muitas tabelas, alias de 3 letras costuma ser mais legível do que 1 letra.

Continue em nosso aplicativo

Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.

ou continue lendo abaixo...
Download App

Baixar o aplicativo

  • Evite alias genéricos como a, b, t1, t2 quando houver mais de duas tabelas.
  • Evite alias que conflitam com nomes de colunas (por exemplo, alias id para uma tabela).
  • Evite mudar o alias da mesma tabela entre queries do mesmo projeto (ex.: customers às vezes c, às vezes cust), a menos que haja motivo.

Alias de coluna: nomeie o significado, não o cálculo

Alias de coluna devem refletir o que o campo representa no contexto do negócio. Em vez de sum_value ou calc1, prefira revenue_total, orders_count, avg_ticket, is_active_customer. O leitor não precisa saber que foi um SUM; ele precisa saber o que aquilo significa.

Também é importante padronizar idioma e estilo: se você usa snake_case em inglês, mantenha. Se o time usa português, mantenha em português. Misturar idiomas tende a gerar nomes inconsistentes e difíceis de buscar.

Quando usar alias explícito mesmo sem necessidade

Alguns bancos permitem omitir AS, mas usar AS melhora a leitura, principalmente em colunas calculadas. Além disso, alias explícito ajuda a evitar confusão quando há funções e expressões longas.

SELECT  o.customer_id AS customer_id,  o.order_id    AS order_id,  o.order_date  AS order_dateFROM orders AS o;

Mesmo que pareça redundante, esse padrão facilita revisões e diffs em controle de versão, porque mudanças ficam mais evidentes.

Não use alias “enganosos”

Um erro comum é dar um alias que sugere uma regra de negócio diferente do que o cálculo faz. Por exemplo, chamar de active_customers uma contagem que na verdade conta clientes com pedido nos últimos 365 dias, quando o negócio define “ativo” como 90 dias. Se a definição é específica, reflita isso no nome: customers_with_orders_last_365d ou customers_active_365d.

Formatação: transforme a query em um documento fácil de escanear

Palavras-chave em maiúsculas e uma cláusula por bloco

Um padrão muito usado é palavras-chave em maiúsculas e cada cláusula começando em uma nova linha. Isso cria “marcos visuais” que permitem localizar rapidamente onde mexer.

SELECT  c.customer_id,  c.customer_name,  o.order_id,  o.order_dateFROM customers AS cINNER JOIN orders AS o  ON o.customer_id = c.customer_idWHERE o.order_date >= DATE '2025-01-01'ORDER BY o.order_date DESC;

Indentação consistente para JOIN e condições

Indentação é mais do que estética: ela mostra hierarquia. Em JOINs, alinhe o ON e quebre condições em linhas separadas quando houver mais de uma. Em filtros, use uma condição por linha para facilitar adicionar/remover regras.

SELECT  o.order_id,  o.customer_id,  o.order_date,  o.statusFROM orders AS oLEFT JOIN order_payments AS op  ON op.order_id = o.order_id AND op.is_refunded = 0WHERE o.status IN ('paid', 'shipped')  AND o.order_date >= DATE '2025-01-01'  AND o.order_date <  DATE '2026-01-01';

Note que a condição op.is_refunded = 0 ficou no ON porque faz parte do relacionamento e evita transformar o LEFT JOIN em INNER JOIN por acidente. Mesmo quando você já domina esse comportamento, a formatação deixa a intenção clara.

Alinhamento vertical: use com moderação

Alinhar colunas e AS pode melhorar leitura, mas pode piorar diffs quando alguém adiciona um campo no meio. Uma prática equilibrada é alinhar apenas em blocos pequenos (por exemplo, no SELECT final) e evitar alinhamento obsessivo em todas as linhas.

Evite SELECT *

Além de riscos de performance e de mudanças silenciosas no schema, SELECT * prejudica legibilidade: ninguém sabe quais colunas são realmente usadas. Prefira listar colunas e ordenar de forma lógica (identificadores, datas, dimensões, métricas).

Comentários úteis e curtos

Comentários devem explicar “por quê” e “o que significa”, não repetir o óbvio. Bons usos: justificar uma regra de negócio, explicar uma exceção, indicar fonte de uma definição. Evite comentários que descrevem a linha literalmente.

SELECT  o.order_id,  o.order_date,  o.total_amount,  CASE WHEN o.status = 'canceled' THEN 1 ELSE 0 END AS is_canceled  -- status 'canceled' inclui cancelamentos manuais e automáticos; não usar 'refund' aquiFROM orders AS o;

Nomes: padrões que evitam ambiguidade e retrabalho

Padronize estilo: snake_case e sem acentos

Para nomes de colunas derivadas e aliases, snake_case tende a ser o mais compatível entre bancos e ferramentas. Evite acentos e caracteres especiais para reduzir problemas de portabilidade e de integrações.

Use prefixos/sufixos semânticos

Alguns padrões ajudam a entender o tipo do campo rapidamente:

  • is_ para booleanos: is_active, is_refunded.
  • has_ para presença: has_email, has_orders.
  • _at para timestamps: created_at, paid_at.
  • _date para datas: order_date.
  • _count, _total, _avg para métricas: orders_count, revenue_total, ticket_avg.

Isso reduz a necessidade de “abrir o cálculo” para entender o que é cada coluna.

Evite nomes genéricos e sobrecarregados

Nomes como value, status, type sem contexto são armadilhas. Prefira order_status, payment_status, customer_type. Em queries com múltiplas entidades, o contexto no nome evita confusão e erros de join/agrupamento.

Não renomeie por renomear

Se a coluna já tem um nome bom e padronizado no schema, manter o nome ajuda consistência. Renomeie quando:

  • o nome original é ambíguo ou ruim;
  • você está criando um campo derivado;
  • você precisa padronizar nomes vindos de fontes diferentes no mesmo resultado.

Estrutura de query: organize como um pipeline de transformação

Separação por etapas: base, enriquecimento, cálculo, saída

Uma estrutura legível costuma seguir etapas claras. Mesmo sem repetir o capítulo de CTEs, vale usar a ideia de “pipeline”: cada etapa faz uma coisa e prepara a próxima. O objetivo é evitar uma única query monolítica com dezenas de expressões e regras misturadas.

Uma forma prática de pensar:

  • Base: seleciona colunas essenciais e aplica filtros fundamentais (escopo).
  • Enriquecimento: adiciona atributos de outras tabelas (dimensões).
  • Cálculo: cria campos derivados e métricas.
  • Saída: seleciona e ordena as colunas finais, com nomes prontos para consumo.

Evite lógica duplicada: centralize regras

Quando a mesma regra aparece em vários lugares (por exemplo, a definição de “pedido válido”), a query fica difícil de manter: alguém ajusta um trecho e esquece outro. Centralize a regra em um único ponto e reutilize o resultado. Mesmo dentro de uma única query, isso pode ser feito criando um campo derivado e usando-o depois, em vez de repetir a expressão.

SELECT  o.order_id,  o.order_date,  o.status,  CASE WHEN o.status IN ('paid', 'shipped', 'delivered') THEN 1 ELSE 0 END AS is_valid_orderFROM orders AS o;

Depois, em vez de repetir status IN (...) em múltiplos filtros e cálculos, use is_valid_order (quando o banco permitir referenciar alias na mesma camada, ou em uma camada acima).

Ordem lógica das colunas no SELECT final

Uma ordem previsível melhora leitura e uso em relatórios. Um padrão comum:

  • Chaves e identificadores: customer_id, order_id.
  • Datas e períodos: order_date, month.
  • Dimensões descritivas: customer_segment, region.
  • Métricas: orders_count, revenue_total.
  • Flags e campos técnicos: is_valid_order, source_system.

Isso reduz o tempo para encontrar campos e evita que métricas fiquem “perdidas” no meio de dimensões.

Passo a passo prático: refatorando uma query para ficar legível

A seguir, um exemplo de refatoração focada em alias, formatação, nomes e estrutura. A ideia é pegar uma query funcional, porém difícil de ler, e transformá-la em algo fácil de revisar e manter.

Passo 1: identifique o objetivo e as entidades envolvidas

Antes de mexer no SQL, escreva em uma frase o que a query entrega. Exemplo: “Listar pedidos de 2025 com nome do cliente e valor total, marcando se o pedido é válido para receita”. Isso ajuda a separar o que é essencial do que é ruído.

Passo 2: comece com uma versão “crua” (pouco legível)

Exemplo de query que funciona, mas é difícil de manter:

select customer_id,customer_name,order_id,order_date,total_amount,case when status in('paid','shipped','delivered') then 1 else 0 end valid from customers c join orders o on o.customer_id=c.customer_id where order_date>='2025-01-01' and order_date<'2026-01-01' and (status<>'canceled' or status is null) order by order_date desc;

Problemas típicos aqui: palavras-chave em minúsculas misturadas, alias inconsistentes (tabela customers sem AS, colunas sem prefixo), nome de coluna derivada genérico (valid), condições comprimidas em uma linha e uma regra confusa (status <> 'canceled' OR status IS NULL) que pode não refletir a intenção.

Passo 3: aplique formatação e padronize alias de tabela

Primeiro, deixe a estrutura visível e padronize alias:

SELECT  c.customer_id,  c.customer_name,  o.order_id,  o.order_date,  o.total_amount,  CASE    WHEN o.status IN ('paid', 'shipped', 'delivered') THEN 1    ELSE 0  END AS validFROM customers AS cINNER JOIN orders AS o  ON o.customer_id = c.customer_idWHERE o.order_date >= DATE '2025-01-01'  AND o.order_date <  DATE '2026-01-01'  AND (o.status <> 'canceled' OR o.status IS NULL)ORDER BY o.order_date DESC;

Mesmo sem mudar a lógica, a leitura melhora. Agora fica fácil discutir a regra do status.

Passo 4: melhore nomes de colunas derivadas e explicite intenção

Troque valid por um nome semântico. Se a regra é “pedido válido para receita”, use is_valid_for_revenue. Se é “pedido não cancelado”, use is_not_canceled. Nomeie conforme o uso.

SELECT  c.customer_id,  c.customer_name,  o.order_id,  o.order_date,  o.total_amount,  CASE    WHEN o.status IN ('paid', 'shipped', 'delivered') THEN 1    ELSE 0  END AS is_valid_for_revenueFROM customers AS cINNER JOIN orders AS o  ON o.customer_id = c.customer_idWHERE o.order_date >= DATE '2025-01-01'  AND o.order_date <  DATE '2026-01-01'  AND (o.status <> 'canceled' OR o.status IS NULL)ORDER BY o.order_date DESC;

Passo 5: reescreva condições para reduzir ambiguidade

Condições com OR costumam ser pontos de erro e de leitura lenta. Se a intenção é “excluir cancelados”, uma forma mais clara é: “status é nulo ou status é diferente de canceled”. Ainda é OR, mas você pode colocar primeiro o caso especial (nulo) e documentar. Se a intenção real é “considerar apenas status válidos para receita”, então o filtro deveria usar a mesma lista do CASE, evitando divergência entre filtro e flag.

Exemplo alinhando filtro e flag (uma única fonte de verdade):

SELECT  c.customer_id,  c.customer_name,  o.order_id,  o.order_date,  o.total_amount,  CASE    WHEN o.status IN ('paid', 'shipped', 'delivered') THEN 1    ELSE 0  END AS is_valid_for_revenueFROM customers AS cINNER JOIN orders AS o  ON o.customer_id = c.customer_idWHERE o.order_date >= DATE '2025-01-01'  AND o.order_date <  DATE '2026-01-01'  AND o.status IN ('paid', 'shipped', 'delivered')ORDER BY o.order_date DESC;

Agora a query fica mais previsível: o resultado contém apenas pedidos válidos para receita, e a flag vira redundante (você pode removê-la se não precisar). Se você precisa manter pedidos inválidos no resultado para auditoria, então não filtre por status; apenas crie a flag e deixe o consumidor decidir.

Passo 6: organize o SELECT final por grupos e evite redundâncias

Se a query é para consumo em relatório, organize colunas por grupos (IDs, datas, dimensões, métricas). Também avalie se campos redundantes devem sair. Exemplo mantendo a flag para auditoria:

SELECT  o.order_id,  o.customer_id,  c.customer_name,  o.order_date,  o.status AS order_status,  o.total_amount,  CASE    WHEN o.status IN ('paid', 'shipped', 'delivered') THEN 1    ELSE 0  END AS is_valid_for_revenueFROM orders AS oINNER JOIN customers AS c  ON c.customer_id = o.customer_idWHERE o.order_date >= DATE '2025-01-01'  AND o.order_date <  DATE '2026-01-01'ORDER BY o.order_date DESC;

Note que order_status deixa explícito o contexto, e a ordem das colunas começa por identificadores.

Checklist rápido de legibilidade para usar no dia a dia

Alias

  • Alias de tabela são consistentes e não genéricos demais.
  • Colunas sempre qualificadas com alias de tabela quando há mais de uma tabela.
  • Alias de coluna descrevem significado de negócio.

Formatação

  • Palavras-chave em maiúsculas (ou minúsculas), mas sempre no mesmo padrão.
  • Uma condição por linha em WHERE/ON quando houver múltiplas regras.
  • Sem SELECT * em queries de relatório/produção.

Nomes

  • Sem nomes genéricos sem contexto (status, type, value).
  • Uso consistente de snake_case e padrões como is_, _at, _count.
  • Evita alias enganosos que não correspondem à regra aplicada.

Estrutura

  • Query organizada em blocos previsíveis e fáceis de escanear.
  • Regras de negócio centralizadas para evitar duplicação e divergência.
  • SELECT final com colunas em ordem lógica para consumo.

Agora responda o exercício sobre o conteúdo:

Ao organizar uma query para melhorar a legibilidade e evitar divergência de regras, qual prática é mais indicada?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Centralizar a regra reduz duplicação e o risco de alguém alterar um trecho e esquecer outro. Isso torna a query mais previsível, fácil de revisar e manter.

Próximo capitúlo

Noções de performance: filtros, índices, planos e como evitar SELECT *

Arrow Right Icon
Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.