CASE adiciona lógica if/then/else a uma consulta SQL: ele verifica uma lista de condições e retorna o resultado da primeira que for verdadeira. Os exemplos funcionam em PostgreSQL, MySQL, SQLite e SQL Server.
Como usar CASE
Liste pares WHEN condition THEN result entre CASE e END. CASE retorna o resultado da primeira condição verdadeira, ou o valor de ELSE se nenhuma for:
CASE
WHEN condition THEN result
[WHEN condition THEN result ...]
[ELSE result]
END
SELECT
CASE
WHEN 72 >= 90 THEN 'Hot'
WHEN 72 >= 60 THEN 'Mild'
ELSE 'Cold'
END;
-- Output: Mild
Quando todas as condições testam a igualdade do mesmo valor, a forma “simples”, mais curta, cita esse valor uma única vez:
SELECT
CASE 'amber'
WHEN 'green' THEN 'Go'
WHEN 'amber' THEN 'Slow down'
WHEN 'red' THEN 'Stop'
ELSE 'Unknown'
END;
-- Output: Slow down
Em uma consulta real, as condições testam colunas, e o CASE adiciona uma nova coluna ao resultado:
-- Input: orders
-- order_id | amount
-- ---------+--------
-- 1001 | 45.00
-- 1002 | 100.00
-- 1003 | 349.99
-- 1004 | 1250.00
SELECT
order_id,
amount,
CASE
WHEN amount < 100 THEN 'Small'
WHEN amount < 500 THEN 'Medium'
ELSE 'Large'
END AS order_size
FROM orders;
-- Output:
-- order_id | amount | order_size
-- ---------+---------+-----------
-- 1001 | 45.00 | Small
-- 1002 | 100.00 | Medium
-- 1003 | 349.99 | Medium
-- 1004 | 1250.00 | Large
Regras importantes
-
A primeira condição verdadeira vence. As condições são verificadas de cima para baixo, então coloque a mais restrita primeiro. Acima,
100.00é Medium porqueamount < 100é falso eamount < 500é verdadeiro. Na ordem errada, valores pequenos nunca chegam ao seu ramo:
SELECT
CASE
WHEN 45 < 500 THEN 'Medium'
WHEN 45 < 100 THEN 'Small' -- can never win
ELSE 'Large'
END;
-- Output: Medium
- Sem ELSE, nenhuma correspondência significa NULL.
SELECT CASE WHEN 72 >= 90 THEN 'Hot' END;
-- Output: NULL
-
Teste NULL com IS NULL.
NULL = NULLnão é verdadeiro, então a forma simples não consegue corresponder a um NULL. Use a forma pesquisada:
SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'no match' END;
-- Output: no match
SELECT CASE WHEN NULL IS NULL THEN 'matched' ELSE 'no match' END;
-- Output: matched
- Todos os resultados precisam de um tipo compatível. Misturar número e texto no mesmo CASE gera erro no PostgreSQL e no SQL Server, então converta o número:
-- Input: products
-- name | stock
-- -------------+------
-- Desk Lamp | 12
-- Office Chair | 0
SELECT name, CASE WHEN stock > 0 THEN stock ELSE 'Sold out' END AS stock
FROM products;
-- PostgreSQL: ERROR: invalid input syntax for type integer: "Sold out"
-- SQL Server: Conversion failed when converting the varchar value 'Sold out' to data type int.
-- (in MySQL, cast with CAST(stock AS CHAR))
SELECT
name,
CASE WHEN stock > 0 THEN CAST(stock AS VARCHAR(10)) ELSE 'Sold out' END AS stock
FROM products;
-- Output:
-- name | stock
-- -------------+---------
-- Desk Lamp | 12
-- Office Chair | Sold out
Sintaxe alternativa
Para uma única condição, você também verá uma função mais curta:
-- MySQL
SELECT IF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild
-- SQL Server and SQLite
SELECT IIF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild
Duas outras funções são atalhos para expressões CASE comuns. COALESCE(nickname, name) significa CASE WHEN nickname IS NOT NULL THEN nickname ELSE name END, e NULLIF(a, b) significa CASE WHEN a = b THEN NULL ELSE a END. Veja o guia de COALESCE em SQL para a primeira.
O MySQL também tem uma instrução CASE para stored procedures, que termina com END CASE. Este post aborda a expressão CASE que você usa em consultas.
Quando usar CASE?
CASE é uma expressão, então funciona em qualquer lugar onde caiba um valor: na lista do SELECT, em ORDER BY e GROUP BY, e dentro de funções de agregação. Também funciona no WHERE, mas ali AND e OR simples costumam ser mais claros. A maioria dos usos se encaixa em um destes cinco.
Agrupar números em faixas
Transforme um número em uma faixa: níveis de preço, tamanhos de pedido, faixas etárias, notas. Escreva as condições de uma ponta da escala até a outra, para que a primeira correspondência seja a correta.
Traduzir códigos em rótulos
Bancos de dados guardam códigos curtos como 'A', 'ENG' ou 'gold'; as pessoas querem palavras. Um CASE simples mapeia cada código para um rótulo, ou para um valor como uma taxa de desconto, e o ELSE captura qualquer código inesperado.
Contar ou somar só algumas linhas
Coloque CASE dentro de COUNT ou SUM para contar ou somar apenas as linhas que atendem a uma condição. COUNT(CASE WHEN ... THEN 1 END) funciona porque linhas sem correspondência retornam NULL, que o COUNT ignora. Uma agregação por condição gera vários totais lado a lado, e é assim que se monta uma tabela dinâmica (pivot) em SQL.
Tratar valores ausentes
Verifique colunas em busca de NULL por ordem de preferência e retorne um rótulo quando todas estiverem vazias. Para um fallback simples, COALESCE é mais curto. CASE é a ferramenta certa quando cada tipo de lacuna exige um resultado diferente.
Ordenar de forma personalizada
A ordem alfabética e a numérica não servem para tudo: tamanhos de roupa, prioridades de tickets, uma lista com produtos em destaque primeiro. Um CASE no ORDER BY dá a cada valor a posição que você quiser.
Exemplos reais de CASE
Classificar produtos por departamento e preço
Um resultado pode ser ele próprio um CASE, assim cada departamento tem suas próprias faixas de preço:
-- Input: products
-- product_name | category | price
-- -----------------+-------------+--------
-- Laptop Pro 14 | Electronics | 1499.00
-- Wireless Earbuds | Electronics | 129.00
-- Leather Jacket | Clothing | 349.00
-- Cotton T-Shirt | Clothing | 19.99
-- Coffee Mug | Kitchen | 12.50
SELECT
product_name,
CASE category
WHEN 'Electronics' THEN
CASE
WHEN price > 1000 THEN 'Premium Electronics'
ELSE 'Standard Electronics'
END
WHEN 'Clothing' THEN
CASE
WHEN price > 200 THEN 'Designer Clothing'
ELSE 'Regular Clothing'
END
ELSE 'Other Products'
END AS product_class
FROM products;
-- Output:
-- product_name | product_class
-- -----------------+---------------------
-- Laptop Pro 14 | Premium Electronics
-- Wireless Earbuds | Standard Electronics
-- Leather Jacket | Designer Clothing
-- Cotton T-Shirt | Regular Clothing
-- Coffee Mug | Other Products
Com mais de dois níveis, CASE aninhado fica difícil de ler. Uma tabela de referência com JOIN costuma ser mais clara.
Aplicar desconto por nível de cliente
Cada código de nível corresponde a uma taxa de desconto, e clientes sem nível não recebem nenhum:
-- Input: customers
-- id | customer_name | tier
-- ---+---------------+-------
-- 1 | Maya Brooks | gold
-- 2 | Leo Martin | silver
-- 3 | Ava Kim | bronze
-- 4 | Noah Price | NULL
-- Input: orders
-- id | customer_id | order_total
-- ----+-------------+------------
-- 101 | 1 | 200.00
-- 102 | 2 | 150.00
-- 103 | 3 | 80.00
-- 104 | 4 | 60.00
SELECT
customer_name,
order_total,
ROUND(order_total * CASE tier
WHEN 'gold' THEN 0.15
WHEN 'silver' THEN 0.10
WHEN 'bronze' THEN 0.05
ELSE 0
END, 2) AS discount
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY o.id;
-- Output:
-- customer_name | order_total | discount
-- --------------+-------------+---------
-- Maya Brooks | 200.00 | 30.00
-- Leo Martin | 150.00 | 15.00
-- Ava Kim | 80.00 | 4.00
-- Noah Price | 60.00 | 0.00
Pivotar vendas mensais em colunas
Um SUM(CASE ...) por mês transforma linhas de vendas em uma coluna para cada mês:
-- Input: sales
-- product_category | sale_date | amount
-- -----------------+------------+-------
-- Books | 2026-01-12 | 40.00
-- Games | 2026-01-20 | 60.00
-- Books | 2026-02-03 | 25.00
-- Books | 2026-03-15 | 30.00
-- Games | 2026-03-28 | 75.00
SELECT
product_category,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_category
ORDER BY product_category;
-- Output:
-- product_category | jan_sales | feb_sales | mar_sales
-- -----------------+-----------+-----------+----------
-- Books | 40.00 | 25.00 | 30.00
-- Games | 60.00 | 0 | 75.00
No SQL Server, use MONTH(sale_date) = 1 em vez de EXTRACT; no SQLite, use strftime('%m', sale_date) = '01'.
Diferenciar valores ausentes de vazios
Dados importados costumam ter tanto NULLs quanto strings vazias. O CASE pode rotular cada um para você saber o que limpar:
-- Input: users
-- id | middle_name
-- ---+------------
-- 1 | Rose
-- 2 |
-- 3 | NULL
SELECT
id,
CASE
WHEN middle_name IS NULL THEN 'Missing'
WHEN middle_name = '' THEN 'Empty'
ELSE middle_name
END AS middle_name
FROM users;
-- Output:
-- id | middle_name
-- ---+------------
-- 1 | Rose
-- 2 | Empty
-- 3 | Missing
Colocar produtos em destaque primeiro
Dê a cada categoria uma posição de ordenação e depois ordene por nome dentro dela:
-- Input: products
-- product_name | category
-- -------------+------------
-- Wool Scarf | Sale
-- Desk Lamp | Featured
-- Bike Helmet | Clearance
-- Smart Watch | New Arrival
-- Air Fryer | Featured
SELECT product_name, category
FROM products
ORDER BY
CASE category
WHEN 'Featured' THEN 1
WHEN 'New Arrival' THEN 2
WHEN 'Sale' THEN 3
ELSE 4
END,
product_name;
-- Output:
-- product_name | category
-- -------------+------------
-- Air Fryer | Featured
-- Desk Lamp | Featured
-- Smart Watch | New Arrival
-- Wool Scarf | Sale
-- Bike Helmet | Clearance
Leitura complementar sobre CASE
Neste blog:
- Guia de COALESCE em SQL: o jeito curto de definir um fallback quando um valor é NULL
- Guia de tabela dinâmica (pivot) em SQL: CASE dentro de SUM e AVG para transformar linhas em colunas
- Guia de ORDER BY em SQL: ordenação, incluindo ordens personalizadas
- Guia de GROUP BY em SQL: o agrupamento em que se baseiam contagens e totais condicionais
- Guia do operador diferente em SQL: por que comparações com NULL nunca correspondem
Documentação oficial:
Beekeeper Studio é um cliente de banco de dados gratuito e open source
A melhor ferramenta de consultas e edição de SQL que já usei. Tem tudo o que preciso para gerenciar meu banco de dados. - ⭐⭐⭐⭐⭐ Mit
O Beekeeper Studio é rápido, intuitivo e fácil de usar. Ele suporta vários bancos de dados e funciona muito bem no Windows, Mac e Linux.
O que os usuários dizem sobre o Beekeeper Studio
"O Beekeeper Studio substituiu completamente meu antigo fluxo de trabalho com SQL. É rápido, intuitivo e torna o trabalho com bancos de dados agradável de novo."
"Já testei muitas GUIs de banco de dados, mas o Beekeeper encontra o equilíbrio perfeito entre recursos e simplicidade. Simplesmente funciona."