SQL CASE WHEN: Lógica Condicional nas Consultas
Lição 3.5 · Tempo de leitura: ~7 min · Tarefas para praticar ↓
A expressão SQL CASE adiciona lógica se-então-senão a uma consulta: verifica as condições em ordem e devolve o valor da primeira que for verdadeira. Nesta lição, você vai aprender as duas formas de CASE, como criar categorias e rótulos no SELECT, como ordenar por uma prioridade personalizada e como usar CASE no WHERE.
As funções das lições anteriores transformam todas as linhas da mesma forma. Muitas vezes, a regra depende dos dados: um pagamento abaixo de $2 é "baixo", acima de $6 é "alto"; um aluguel sem data de devolução está "não devolvido". O CASE permite escrever essas regras diretamente em SQL, em vez de tratá-las no código da aplicação.
Sintaxe do CASE
O CASE tem duas formas.
CASE de Pesquisa
Cada WHEN contém a sua própria condição. É a forma mais flexível e a mais comum:
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE default_result
END
CASE Simples
Uma expressão é comparada com uma lista de valores:
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE default_result
END
Como o CASE É Avaliado
- As condições são verificadas de cima para baixo.
- É devolvido o resultado da primeira condição verdadeira; as restantes não são verificadas.
- Se nenhuma condição for verdadeira, é devolvido o valor do
ELSE. - Se não houver
ELSE, o resultado éNULL.
O CASE é uma expressão, não uma instrução separada: devolve um valor e pode ser usado em qualquer lugar onde um valor é permitido, no SELECT, no WHERE ou no ORDER BY.
CASE no SELECT: Categorias e Rótulos
Níveis de Pagamento
SELECT payment_id,
amount,
CASE
WHEN amount < 2 THEN 'Low'
WHEN amount < 6 THEN 'Medium'
ELSE 'High'
END AS payment_level
FROM payment
LIMIT 10;
Resultado: dez pagamentos, cada um com um nível: abaixo de $2 "Low", de $2 até menos de $6 "Medium", $6 ou mais "High".
A ordem das condições importa. Um pagamento de $1 também satisfaz amount < 6, mas recebe "Low" porque vence o primeiro ramo correspondente. Graças a isso, a segunda condição não precisa de limite inferior.
Status Legível
SELECT rental_id,
rental_date,
CASE
WHEN return_date IS NULL THEN 'Not returned'
ELSE 'Returned'
END AS rental_status
FROM rental
ORDER BY rental_date DESC
LIMIT 10;
Resultado: os aluguéis mais recentes com um status em texto em vez de uma data de devolução vazia ou preenchida.
CASE Simples para Códigos
A forma simples é prática quando uma coluna guarda códigos:
SELECT title,
rating,
CASE rating
WHEN 'G' THEN 'General audiences'
WHEN 'PG' THEN 'Parental guidance'
WHEN 'PG-13' THEN 'Parents strongly cautioned'
WHEN 'R' THEN 'Restricted'
ELSE 'Adults only'
END AS rating_description
FROM film
LIMIT 10;
Resultado: filmes com uma descrição legível da sua classificação.
CASE no ORDER BY: Ordem de Ordenação Personalizada
A ordem alfabética dos códigos de classificação (G, NC-17, PG, PG-13, R) não corresponde ao seu significado. O CASE transforma cada código num número de prioridade:
SELECT title, rating
FROM film
ORDER BY CASE rating
WHEN 'G' THEN 1
WHEN 'PG' THEN 2
WHEN 'PG-13' THEN 3
WHEN 'R' THEN 4
ELSE 5
END,
title;
Resultado: filmes da classificação mais leve à mais restrita; dentro de cada classificação, pelo título.
A mesma técnica coloca as linhas importantes no topo:
SELECT rental_id, rental_date, return_date
FROM rental
ORDER BY CASE WHEN return_date IS NULL THEN 0 ELSE 1 END,
rental_date DESC
LIMIT 20;
Resultado: primeiro os aluguéis não devolvidos, depois os restantes, os mais recentes primeiro em cada grupo.
CASE no WHERE
O CASE pode devolver um valor para uma condição, por exemplo um limite que depende de outra coluna:
SELECT payment_id, staff_id, amount
FROM payment
WHERE amount >= CASE
WHEN staff_id = 1 THEN 5
ELSE 3
END
LIMIT 10;
Resultado: pagamentos de pelo menos $5 para o funcionário 1 e de pelo menos $3 para os outros.
A maioria desses filtros também pode ser escrita com AND e OR: WHERE (staff_id = 1 AND amount >= 5) OR (staff_id <> 1 AND amount >= 3). Escolha a versão mais fácil de ler: para dois ramos, costuma ser OR; para muitos ramos, CASE.
Dicas Práticas
- Escreva sempre o
ELSE. Sem ele, valores inesperados viramNULL, e essas linhas passam facilmente despercebidas. - Devolva um único tipo de dados. Misturar texto e números em ramos diferentes leva a conversões implícitas e surpresas.
- Ordene as condições do mais específico para o mais geral. Vence o primeiro ramo verdadeiro.
- Na Lição 4.4, você vai usar
CASEdentro de funções de agregação para contar linhas por categoria numa única consulta.
Principais conclusões:
- O
CASEdevolve o resultado da primeira condiçãoWHENverdadeira, ou oELSEse nenhuma for verdadeira. - O
CASEde pesquisa verifica quaisquer condições; oCASEsimples compara uma expressão com valores. - Sem
ELSE, o resultado éNULL. - No
SELECT, oCASEcria categorias e rótulos legíveis. - No
ORDER BY, define uma ordem de ordenação personalizada; noWHERE, pode fazer um filtro depender de outras colunas.
Perguntas Frequentes
Qual é a diferença entre CASE simples e CASE de pesquisa?
O CASE simples compara uma expressão com uma lista de valores: CASE rating WHEN 'G' THEN .... O CASE de pesquisa verifica uma condição separada em cada ramo: CASE WHEN amount < 2 THEN .... O CASE de pesquisa faz tudo o que a forma simples faz, além de intervalos, verificações de NULL e condições sobre várias colunas.
O que o CASE devolve se nenhuma condição for verdadeira e não houver ELSE?
NULL. Para evitar surpresas, adicione sempre um ramo ELSE com um valor padrão explícito.
Existe uma função IF em SQL?
O CASE é a forma padrão. MySQL e MariaDB também têm IF(condition, value_if_true, value_if_false), e o SQL Server tem IIF(), mas não são portáveis.