Instrução SQL CASE WHEN: sintaxe, exemplos reais e erros comuns

  1. Início
  2. Blog
  3. Bancos de dados e SQL

Bancos de dados e SQL

Instrução SQL CASE WHEN: Sintaxe, exemplos reais e erros comuns

CASE WHEN é como você escreve a lógica if-then em SQL. Aprenda os dois formulários e use-os para rótulos, relatórios de estilo dinâmico, classificação personalizada e atualizações seguras, evitando as armadilhas NULL e de ordem.

8 min de leitura
Instrução SQL CASE WHEN: sintaxe, exemplos reais e erros comuns

Principais pontos

  • CASE retorna um valor baseado na primeira condição que é verdadeira.
  • Coloque as condições mais específicas em primeiro lugar, ou as posteriores poderão nunca ser alcançadas.
  • Sem ELSE, as linhas sem correspondência retornam NULL.
  • Dentro de SUM ou COUNT, CASE transforma uma consulta em um relatório compacto em estilo pivô.

A maioria dos relatórios precisa de alguma lógica: rotular os pedidos como grandes ou pequenos, contar os pedidos pagos e pendentes lado a lado ou mostrar os itens urgentes primeiro. SQL CASE WHEN lida com tudo isso diretamente dentro de uma consulta e funciona em todos os principais bancos de dados.

Executamos todas as consultas aqui no SQLite 3.50 e os resultados mostrados vêm dessa execução. CASE faz parte do SQL padrão, portanto se comporta da mesma maneira no PostgreSQL, MySQL, SQL Server e Oracle para estes exemplos.

O que é CASO QUANDO?

CASE é uma expressão, não um comando separado. Ele avalia as condições em ordem e retorna um valor, para que possa ir a qualquer lugar onde um valor seja permitido: em SELECT, WHERE, GROUP BY, ORDER BY ou dentro de funções. Sempre termina com END.

CASE
  WHEN condition1 THEN result1
  WHEN condition2 THEN result2
  ELSE fallback
END

A tabela de amostra

CREATE TABLE orders (id INT, customer TEXT, total INT, status TEXT);

INSERT INTO orders VALUES
 (1,'Asha',1200,'paid'), (2,'Ben',300,'pending'),
 (3,'Asha',800,'paid'), (4,'Chitra',2500,'shipped'),
 (5,'Dev',150,'cancelled'), (6,'Ben',NULL,'pending');

Observe que o pedido 6 não tem total. Essa linha importa mais tarde.

CASO pesquisado

Esta é a forma mais flexível, já que cada WHEN tem uma condição completa própria:

SELECT id, total,
       CASE
         WHEN total >= 1000 THEN 'large'
         WHEN total >= 500 THEN 'medium'
         ELSE 'small'
       END AS size
FROM orders;

-- 1 | 1200 | large
-- 2 |  300 | small
-- 3 |  800 | medium
-- 4 | 2500 | large
-- 5 |  150 | small
-- 6 | NULL | small

Olhe para a última linha. O pedido 6 não tem total, mas é rotulado como “pequeno”. Ambas as comparações com NULL não eram verdadeiras, então caiu para ELSE. Mostramos como corrigir isso na seção NULL. Sempre dê um nome ao resultado usando AS, ou você pode obter um nome de coluna estranho.

CASO Simples

Ao comparar uma coluna com valores fixos, a forma mais curta é melhor:

SELECT id,
       CASE status
         WHEN 'paid' THEN 'Complete'
         WHEN 'shipped' THEN 'Complete'
         WHEN 'pending' THEN 'Waiting'
       END AS label
FROM orders;

-- 1 | Complete
-- 2 | Waiting
-- 3 | Complete
-- 4 | Complete
-- 5 | NULL
-- 6 | Waiting
Formulário Compara Pode usar intervalos? Melhor para
Simples Uma expressão para igualdade Não Mapeando códigos para rótulos
Pesquisado Qualquer condição por filial Sim Intervalos, múltiplas colunas, verificações NULL

O pedido é importante

CASE para na primeira condição verdadeira e este é o bug lógico mais comum. Troque as duas condições da nossa consulta anterior:

SELECT id, total,
       CASE
         WHEN total >= 500 THEN 'medium'
         WHEN total >= 1000 THEN 'large'
         ELSE 'small'
       END AS size
FROM orders WHERE id IN (1, 4);

-- 1 | 1200 | medium
-- 4 | 2500 | medium

Agora nada pode ser “grande”. Um total de 2.500 também é pelo menos 500, então o primeiro ramo vence e o segundo nunca é alcançado. Nenhum erro aparece, apenas rótulos errados. Para intervalos, coloque primeiro a condição mais restritiva ou escreva intervalos completos, como total >= 500 AND total < 1000.

O que acontece sem MAIS?

Em nosso exemplo CASE simples acima, o pedido 5 foi cancelado e nenhuma filial tratou disso, então o resultado foi NULL. Às vezes é exatamente isso que você deseja, como mostra a próxima seção. Mas ao criar rótulos, um ELSE 'other' claro geralmente é melhor, pois torna visíveis valores inesperados em vez de deixar espaços em branco em um relatório.

Dica: Todas as ramificações devem retornar o mesmo tipo. Misturar texto e números funciona vagamente no SQLite, mas bancos de dados mais rígidos, como o PostgreSQL, gerarão um erro ou tentarão converter valores de maneiras que você não pretendia.

Relatórios de estilo dinâmico com SUM

Este é um dos padrões mais úteis no SQL diário. Agrupar CASE em um agregado transforma linhas em colunas, com uma linha por cliente:

SELECT customer,
       SUM(CASE WHEN status = 'paid' THEN total ELSE 0 END) AS paid,
       SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending_orders
FROM orders
GROUP BY customer
ORDER BY customer;

-- Asha   | 2000 | 0
-- Ben    |    0 | 2
-- Chitra |    0 | 0
-- Dev    |    0 | 0

Uma consulta agora fornece a receita paga e o número de pedidos pendentes, sem necessidade de consultas ou junções separadas. O padrão funciona em quase todos os bancos de dados, ao contrário da sintaxe dedicada PIVOT que apenas alguns oferecem. Se GROUP BY for novo para você, leia SQL GROUP BY e HAVING.

Contagens condicionais

COUNT ignora NULLs, então um CASE sem ELSE conta apenas as linhas que correspondem:

SELECT COUNT(*) AS all_orders,
       COUNT(CASE WHEN status = 'paid' THEN 1 END) AS paid_orders,
       COUNT(CASE WHEN total >= 1000 THEN 1 END) AS large_orders
FROM orders;

-- 6 | 2 | 2

Tenha cuidado: se você adicionar ELSE 0 dentro de COUNT, todas as linhas serão contadas, porque 0 não é NULL. Use ELSE 0 com SUM e deixe de fora com COUNT. PostgreSQL e SQLite também suportam COUNT(*) FILTER (WHERE ...), que é bem lido, mas não está disponível em todos os lugares.

Agrupando por um CASE

Você pode criar seus próprios intervalos e resumi-los:

SELECT CASE WHEN total >= 1000 THEN 'large' ELSE 'other' END AS bucket,
       COUNT(*)
FROM orders
GROUP BY bucket
ORDER BY bucket;

-- large | 2
-- other | 4

O agrupamento pelo alias funciona em SQLite, PostgreSQL e MySQL. O SQL Server não permite isso, então você teria que repetir a expressão inteira ou colocar a consulta em uma CTE ou subconsulta primeiro.

Classificação personalizada com ORDER BY

A ordem alfabética raramente é o que uma empresa deseja. CASE permite definir seu próprio pedido:

SELECT id, status FROM orders
ORDER BY CASE status
           WHEN 'pending' THEN 1
           WHEN 'paid' THEN 2
           ELSE 3
         END, id;

-- 2 | pending
-- 6 | pending
-- 1 | paid
-- 3 | paid
-- 4 | shipped
-- 5 | cancelled

Os pedidos pendentes vêm primeiro, o que é útil para uma fila de trabalho. A segunda coluna de classificação, id, mantém as linhas em uma ordem previsível dentro de cada grupo.

CASO em ATUALIZAÇÃO

CASE permite que uma instrução aplique alterações diferentes em linhas diferentes. Aqui, pequenos pedidos pendentes são sinalizados para revisão:

UPDATE orders
SET status = CASE
               WHEN status = 'pending' AND total < 500 THEN 'review'
               ELSE status
             END;

SELECT id, status FROM orders WHERE customer = 'Ben';

-- 2 | review
-- 6 | pending

O ELSE status mantém as outras linhas inalteradas. Deixá-lo de fora é perigoso, porque linhas sem correspondência seriam definidas como NULL. Sem uma cláusula WHERE, esta instrução também afeta todas as linhas, portanto, em tabelas grandes, adicione um filtro e considere agrupar a alteração em uma transação para que você possa verificar o resultado antes de confirmar. Observe também que a ordem 6 não mudou, porque seu total NULL não satisfez total < 500.

Armadilhas NULAS

NULL causa dois problemas distintos com CASE. Primeiro, a forma simples compara usando igualdade, e nada é igual a NULL, nem mesmo o próprio NULL:

SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'not matched' END;

-- not matched

Então CASE col WHEN NULL nunca corresponde. Use o formulário pesquisado com IS NULL. Em segundo lugar, como vimos na ordem 6, um valor NULL escapa das comparações e chega a ELSE. A solução é verificar primeiro:

SELECT id,
       CASE
         WHEN total IS NULL THEN 'unknown'
         WHEN total >= 1000 THEN 'large'
         ELSE 'other'
       END AS size
FROM orders WHERE id IN (1, 2, 6);

-- 1 | large
-- 2 | other
-- 6 | unknown

O pedido 6 agora recebe um rótulo honesto. Nosso guia sobre valores SQL NULL aborda esse comportamento na íntegra.

CASE versus outras opções

Opção Funciona em Use-o quando
CASO Todos os principais bancos de dados Você quer lógica portátil
COALESCER Todos os principais bancos de dados Você só precisa de um substituto para NULL
IF() MySQL Uma escolha simples e bidirecional
IIF() SQL Server, SQLite Uma escolha simples e bidirecional
DECODE() Oráculo Código Oracle mais antigo
Tabela de pesquisa Todos O mapeamento é longo ou muda frequentemente

Essa última opção merece uma reflexão. Se um CASE crescer para trinta ramificações e aparecer em cinco consultas, mova o mapeamento para uma tabela e junte-se a ela. Então, uma alteração é uma atualização de linha única, em vez de uma alteração de código em cinco locais.

Erros comuns

  • Ordem de condição errada. Uma condição ampla primeiro oculta as mais restritas.
  • Esquecimento END. Este é o erro de sintaxe mais frequente.
  • Usando WHEN NULL. Nunca corresponde, então use WHEN col IS NULL.
  • Adicionando ELSE 0 dentro de COUNT. Conta todas as linhas.
  • Omitindo ELSE em um UPDATE. Ele pode limpar valores com NULL.
  • Filtragem por CASE em WHERE. Pode impedir que um índice seja usado. Consulte nosso guia sobre otimização de consultas SQL.

Considerações finais

CASE WHEN é um pequeno recurso que faz muito trabalho. Lembre-se de três regras: a primeira ramificação verdadeira vence, as linhas sem correspondência tornam-se NULL sem ELSE e NULL precisa de sua própria verificação. Para praticar, pegue um relatório que você está construindo atualmente com diversas consultas e tente produzi-lo como uma consulta usando SUM(CASE ...).

Perguntas frequentes

O que CASE WHEN faz no SQL?

Ele adiciona lógica if-then a uma consulta. O SQL verifica cada condição em ordem e retorna o valor da primeira que for verdadeira ou o valor ELSE se nenhum for.

O que acontece se não houver ELSE em uma instrução CASE?

As linhas que não correspondem a nenhuma condição retornam NULL. Isso é útil dentro de COUNT, mas em rótulos e atualizações pode causar espaços em branco ou perda de dados.

Posso usar CASE em uma cláusula WHERE?

Sim, porque é uma expressão. No entanto, as condições simples AND e OR são geralmente mais claras e são mais propensas a fazer uso de um índice.

Qual é a diferença entre CASE simples e pesquisado?

CASE simples compara uma expressão com valores fixos para igualdade. O CASE pesquisado possui uma condição completa em cada WHEN, portanto pode lidar com intervalos e verificações de NULL.

As instruções CASE podem ser aninhadas?

Sim, um CASE pode aparecer dentro de outro. Porém, o aninhamento profundo fica difícil de ler, então considere combinar condições com AND ou usar uma tabela de pesquisa.

Continue aprendendo

Trabalhe com Stack Quora

Precisa de ajuda com testes, WordPress ou SEO?

Ajudamos as equipes a fornecer software melhor e a expandir seus sites. Conte-nos no que você está trabalhando e sugeriremos um próximo passo claro.

Continue lendo

Mais guias sobre testes, IA e desenvolvimento moderno

Gostou deste artigo? Escolha um tópico e vá direto para nossos tutoriais mais recentes.

Inteligência artificial

Explicação das alucinações de IA: por que os modelos de linguagem inventam as coisas e como reduzi-las

Explicação das alucinações de IA: o que são, por que os modelos de linguagem as produzem, tipos comuns, como reduzi-las com aterramento e instruções…

Leia o artigo →
DevOps

Variáveis de ambiente explicadas: arquivos .env, segredos e configuração bem feitos

Variáveis de ambiente explicadas com exemplos de Python que executamos: leitura e configuração, por que cada valor é uma string, arquivos .env, hera…

Leia o artigo →
Desenvolvimento de software

Explicação da limitação de taxa de API: algoritmos, cabeçalhos e tratamento de erros 429

Limitação de taxa de API explicada com uma simulação que executamos: token bucket, janela fixa, janela deslizante, 429 respostas, cabeçalhos de limi…

Leia o artigo →
Automação de testes

Zombando em Python: unittest.mock, patch e os erros que fazem os testes mentirem

Zombaria em Python com unittest.mock, testado: Mock e return_value, side_effect, patch onde um nome é usado, especificação e autospec, zombaria de d…

Leia o artigo →
Teste de software

Cobertura de código explicada: cobertura de linha versus filial e o que 100% realmente significa

Cobertura de código explicada com uma execução cobertura.py real: cobertura de linha, ramal e condição, leitura de um relatório, por que 100% de cob…

Leia o artigo →
Bancos de dados e SQL

DELETE vs TRUNCATE vs DROP em SQL: diferenças, reversão e quando usar cada um

DELETE vs TRUNCATE vs DROP explicado com SQL testado: o que cada um remove, rollback, aciona, redefinição de identidade, velocidade e como PostgreSQ…

Leia o artigo →
Bancos de dados e SQL

Exibições SQL explicadas: crie, use e evite as armadilhas, com exemplos

Visualizações SQL explicadas com consultas que executamos: criação de uma visualização, resultados ao vivo, ocultação de colunas, desempenho, visual…

Leia o artigo →
Desenvolvimento de software

Interface TypeScript vs tipo: diferenças reais, testadas com o compilador

Interface TypeScript versus tipo, verificada com o compilador real: o que ambos podem fazer, o que apenas um pode fazer, mesclagem de declarações, e…

Leia o artigo →
Desenvolvimento de software

Python *args e **kwargs explicados: funções flexíveis com exemplos claros

Python *args e **kwargs explicados com o código que executamos: empacotamento e descompactação, ordem dos parâmetros, argumentos somente de palavras…

Leia o artigo →
Desenvolvimento de software

Funções Python Lambda: sintaxe, usos reais e quando não usá-los

Funções lambda do Python explicadas com o código que executamos: sintaxe, classificação com chave, mapa e filtro, fechamentos, armadilha de ligação …

Leia o artigo →
Inteligência artificial

O que são agentes de IA? Como eles funcionam, com um loop de agente simples que você pode executar

O que são agentes de IA? Um guia simples para o loop do agente, ferramentas, memória e proteções, com um pequeno loop Python que executamos, riscos …

Leia o artigo →
DevOps

Monitoramento versus observabilidade: a verdadeira diferença, com logs, métricas e rastreamentos

Explicação do monitoramento versus observabilidade: falhas conhecidas e desconhecidas, logs, métricas e rastreamentos, um passo a passo do incidente…

Leia o artigo →
DevOps

Docker Volumes vs Bind Mounts: persista os dados do contêiner da maneira certa

Volumes Docker versus montagens de ligação explicadas: por que os dados do contêiner desaparecem, volumes nomeados, montagens de ligação, tmpfs, exe…

Leia o artigo →
Automação de testes

TDD vs BDD: principais diferenças, um recurso criado de ambas as maneiras e quando usar cada um

TDD vs BDD explicado com um recurso de desconto construído em ambos os sentidos: refatoração vermelho-verde com o código que executamos, cenários da…

Leia o artigo →
Teste de software

Teste de aceitação do usuário (UAT): processo, lista de verificação e exemplos reais

Explicação do teste de aceitação do usuário: quem o executa, como ele difere do controle de qualidade, um processo de sete etapas, um modelo de caso…

Leia o artigo →
Bancos de dados e SQL

Valores SQL NULL explicados: IS NULL, COALESCE, NULLIF e as armadilhas a serem evitadas

Valores SQL NULL explicados com consultas que executamos: lógica de três valores, IS NULL, COALESCE, NULLIF, como agregações, junções e classificaçã…

Leia o artigo →
Bancos de dados e SQL

Instrução SQL CASE WHEN: sintaxe, exemplos reais e erros comuns

SQL CASE WHEN explicado com consultas que executamos: formulários simples e pesquisados, ordem de condição, pivôs com SUM, truques COUNT, classifica…

Leia o artigo →
Desenvolvimento de software

O que é JWT? JSON Web Tokens explicados com um exemplo prático

O que é JWT? JSON Web Tokens explicados: as três partes, um token construído e adulterado no código que executamos, JWT vs sessões, armazenamento, t…

Leia o artigo →
Desenvolvimento de software

Loop de eventos JavaScript explicado: pilha de chamadas, microtarefas e temporizadores com exemplos

O loop de eventos JavaScript explicado com o código que executamos: pilha de chamadas, filas de tarefas e microtarefas, por que setTimeout 0 não é i…

Leia o artigo →
Desenvolvimento de software

Geradores Python e rendimento explicado: economize memória com exemplos reais

Geradores Python e rendimento explicados com o código que executamos: como eles pausam e reiniciam, medem economia de memória, pipelines, sequências…

Leia o artigo →
Inteligência artificial

O que são incorporações? Similaridade de vetores e cossenos explicada de forma simples

O que são incorporações? Um guia em linguagem simples para vetores, similaridade de cossenos e pesquisa semântica, com um pequeno exemplo que execut…

Leia o artigo →
DevOps

Implantação azul-verde vs canário: diferenças, compensações e como escolher

Explicação da implantação azul-verde versus canário: como cada um funciona, custo, risco e reversão, agrupamento estável de usuários que testamos, m…

Leia o artigo →
Desenvolvimento de software

Git merge vs rebase: diferenças, exemplos e quando usar cada um

Git merge vs rebase explicado com saída real do log, uma tabela comparativa, a regra de ouro do rebase e um fluxo de trabalho seguro para equipes.

Leia o artigo →
Desenvolvimento de software

List comprehension em Python: sintaxe, exemplos e quando evitar

List comprehension em Python explicada: sintaxe, filtros, if-else, laços aninhados, tempos medidos e quando um laço for comum é a melhor escolha.

Leia o artigo →
Bancos de dados e SQL

SQL JOIN explicado com exemplos (Inner, Left, Right, Full)

Entenda os joins SQL passo a passo com tabelas e consultas de exemplo: INNER, LEFT, RIGHT, FULL, CROSS e SELF, além de erros comuns e dicas de desem…

Leia o artigo →