Expressões Condicionais
Expressões Condicionais
Imagine que você está fazendo um pedido em um restaurante e o garçom pergunta: "Você prefere picante ou não-picante? Leve, médio, ou extra forte?" — isso é lógica condicional: dar respostas diferentes com base em situações diferentes. O CASE WHEN no SQL funciona da mesma forma: retornar valores diferentes com base em condições diferentes, tornando seus resultados de consulta mais flexíveis e significativos.
1. Conceitos Fundamentais
Sintaxe Simple CASE
Simple CASE compara uma expressão contra múltiplos valores, semelhante a uma instrução switch em linguagens de programação.
CASE expressao
WHEN valor1 THEN resultado1
WHEN valor2 THEN resultado2
...
ELSE resultado_padrao
END
-- Retornar descrições em português com base no status do pedido
SELECT order_id, status,
CASE status
WHEN 'completed' THEN 'Concluído'
WHEN 'shipped' THEN 'Enviado'
WHEN 'pending' THEN 'Pendente'
WHEN 'cancelled' THEN 'Cancelado'
ELSE 'Status Desconhecido'
END AS descricao_status
FROM orders;
Sintaxe Searched CASE
Searched CASE usa expressões condicionais, oferecendo mais flexibilidade para lógica complexa.
CASE
WHEN condicao1 THEN resultado1
WHEN condicao2 THEN resultado2
...
ELSE resultado_padrao
END
-- Classificar níveis salariais
SELECT first_name, last_name, salary,
CASE
WHEN salary >= 15000 THEN 'Alto'
WHEN salary >= 10000 THEN 'Médio'
WHEN salary >= 7000 THEN 'Padrão'
ELSE 'Nível Inicial'
END AS nivel_salarial
FROM employees;
>, <, LIKE, IS NULL e quaisquer outras condições. Searched CASE é recomendado para a maioria dos cenários por ser mais flexível.
CASE no SELECT
Usar CASE na lista de colunas do SELECT permite avaliação condicional para cada linha, gerando novas colunas calculadas.
SELECT
CONCAT(first_name, last_name) AS nome,
salary,
CASE
WHEN salary >= 12000 THEN 'Sênior'
WHEN salary >= 8000 THEN 'Pleno'
ELSE 'Júnior'
END AS nivel
FROM employees;
CASE no ORDER BY
Use CASE para definir regras de ordenação personalizadas para "ordenar por ordem especificada".
-- Ordenação personalizada por status: Pendente > Enviado > Concluído > Cancelado
SELECT order_id, status, total_amount
FROM orders
ORDER BY
CASE status
WHEN 'pending' THEN 1
WHEN 'shipped' THEN 2
WHEN 'completed' THEN 3
WHEN 'cancelled' THEN 4
END;
CASE no GROUP BY
Combinado com funções de agregação, isso permite estatísticas condicionais (pivô de linhas para colunas), uma técnica comum em análise de dados.
-- Contar pedidos por status
SELECT
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS concluidos,
SUM(CASE WHEN status = 'shipped' THEN 1 ELSE 0 END) AS enviados,
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pendentes,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) AS cancelados
FROM orders;
CASE no UPDATE
Use CASE em instruções UPDATE para atualizações condicionais em lote, completando múltiplas operações de lógica de atualização em uma única instrução SQL.
-- Ajustar salário com base no desempenho
UPDATE employees
SET salary = CASE
WHEN salary < 8000 THEN salary * 1.15
WHEN salary < 12000 THEN salary * 1.10
ELSE salary * 1.05
END;
IF / IFNULL / COALESCE
O MySQL fornece funções condicionais mais concisas que o CASE:
| Função | Sintaxe | Finalidade |
|---|---|---|
IF |
IF(condicao, valor_verdadeiro, valor_falso) |
Escolha binária simples |
IFNULL |
IFNULL(expressao, substituicao) |
Retornar substituição quando NULL |
COALESCE |
COALESCE(valor1, valor2, ...) |
Retornar o primeiro valor não-NULL |
-- IF: escolha binária simples
SELECT IF(salary > 10000, 'Alto', 'Normal') AS nivel FROM employees;
-- IFNULL: lidar com NULL
SELECT IFNULL(department_id, 0) AS department_id FROM employees;
-- COALESCE: retornar primeiro não-NULL
SELECT COALESCE(commission, bonus, 0) AS bonus FROM employees;
COALESCE é uma função padrão SQL que suporta múltiplos argumentos; IFNULL é específica do MySQL e suporta apenas dois argumentos. COALESCE é recomendada para melhor compatibilidade.
2. Sintaxe Básica
Sintaxe Completa do CASE WHEN
-- Simple CASE
CASE expressao
WHEN valor1 THEN resultado1
WHEN valor2 THEN resultado2
[ELSE resultado_padrao]
END
-- Searched CASE
CASE
WHEN condicao1 THEN resultado1
WHEN condicao2 THEN resultado2
[ELSE resultado_padrao]
END
Sintaxe de Funções Condicionais
IF(condicao, valor_verdadeiro, valor_falso)
IFNULL(expressao, substituicao)
COALESCE(valor1, valor2, ..., valorN)
COALESCE pode substituir IFNULL e suporta múltiplos valores de fallback — é recomendada.
Exemplo: Adicionar Rótulos de Status e Prioridade aos Pedidos (Dificuldade ⭐)
SELECT
order_id,
CONCAT(e.first_name, e.last_name) AS responsavel,
o.total_amount AS valor,
CASE status
WHEN 'completed' THEN '✅ Concluído'
WHEN 'shipped' THEN '🚚 Enviado'
WHEN 'pending' THEN '⏳ Pendente'
WHEN 'cancelled' THEN '❌ Cancelado'
ELSE '❓ Desconhecido'
END AS rotulo_status,
CASE
WHEN total_amount >= 3000 THEN 'Alta'
WHEN total_amount >= 1000 THEN 'Média'
ELSE 'Baixa'
END AS prioridade
FROM orders o
LEFT JOIN employees e ON o.employee_id = e.employee_id
ORDER BY
CASE
WHEN total_amount >= 3000 THEN 1
WHEN total_amount >= 1000 THEN 2
ELSE 3
END;
Saída:
order_id | responsavel | valor | rotulo_status | prioridade
---------+-------------+----------+------------------+-----------
1005 | ZhaoMin | 4100.00 | ✅ Concluído | Alta
1003 | ZhaoMin | 3200.00 | 🚚 Enviado | Alta
1006 | WangQiang | 2800.00 | ❌ Cancelado | Média
1001 | WangQiang | 2500.00 | ✅ Concluído | Média
1002 | WangQiang | 1800.00 | ✅ Concluído | Média
1004 | ZhangWei | 950.00 | ⏳ Pendente | Baixa
Abordagem da consulta:
- O primeiro CASE converte status em inglês para descrições com rótulos
- O segundo CASE classifica a prioridade pelo valor
- O CASE no ORDER BY ordena por prioridade
Exemplo: Contar Funcionários por Nível Salarial por Departamento (Dificuldade ⭐⭐)
SELECT
d.department_name AS departamento,
COUNT(*) AS total,
SUM(CASE WHEN e.salary >= 12000 THEN 1 ELSE 0 END) AS salario_alto,
SUM(CASE WHEN e.salary >= 8000 AND e.salary < 12000 THEN 1 ELSE 0 END) AS salario_medio,
SUM(CASE WHEN e.salary < 8000 THEN 1 ELSE 0 END) AS salario_padrao,
AVG(e.salary) AS salario_medio_geral
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id
GROUP BY d.department_name
ORDER BY salario_medio_geral DESC;
Saída:
departamento | total | salario_alto | salario_medio | salario_padrao | salario_medio_geral
-------------+-------+-------------+---------------+----------------+--------------------
Technology | 2 | 1 | 1 | 0 | 10750.00
Sales | 2 | 1 | 1 | 0 | 9500.00
Marketing | 1 | 0 | 0 | 1 | 7500.00
NULL | 1 | 0 | 1 | 0 | 9000.00
Abordagem da consulta:
- GROUP BY agrupa por departamento
- Cada SUM(CASE ...) conta funcionários que atendem à condição, alcançando pivô de linhas para colunas
- Simultaneamente calcula o salário médio como referência
3. Cenários Comuns de Aplicação
Cenário 1: Rótulos Dinâmicos — Marcar Funcionários com Base em Condições Multidimensionais
SELECT
CONCAT(e.first_name, e.last_name) AS nome,
d.department_name AS departamento,
e.salary,
CASE
WHEN e.salary >= 12000 AND d.department_name = 'Technology' THEN 'Equipe Técnica Principal'
WHEN e.salary >= 12000 THEN 'Funcionário Sênior'
WHEN e.salary >= 8000 AND e.hire_date < '2023-06-01' THEN 'Pleno Experiente'
WHEN e.salary >= 8000 THEN 'Funcionário Pleno'
ELSE 'Funcionário Júnior'
END AS tag_funcionario
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id
ORDER BY e.salary DESC;
Saída:
nome | departamento | salary | tag_funcionario
----------+-------------+-----------+----------------------------
ZhangWei | Technology | 12000.00 | Equipe Técnica Principal
ZhaoMin | Sales | 11000.00 | Funcionário Sênior
LiNa | Technology | 9500.00 | Pleno Experiente
ChenJing | NULL | 9000.00 | Funcionário Pleno
WangQiang | Sales | 8000.00 | Pleno Experiente
LiuYang | Marketing | 7500.00 | Funcionário Júnior
Cenário 2: UPDATE + CASE para Atualizações Condicionais em Lote
-- Ajustar salário com base no tempo de serviço e departamento
UPDATE employees
SET salary = CASE
WHEN department_id = 1 AND hire_date < '2023-01-01' THEN salary * 1.15
WHEN department_id = 1 THEN salary * 1.10
WHEN department_id = 2 THEN salary * 1.08
WHEN department_id IS NULL THEN salary * 1.05
ELSE salary * 1.03
END;
❓ Perguntas Frequentes
P: Qual a diferença entre CASE WHEN e IF? Qual devo usar? R:
IFsó pode lidar com escolhas binárias (verdadeiro/falso) e é adequado para cenários simples;CASE WHENpode lidar com múltiplos ramos de condições e é adequado para lógica complexa. No MySQL,IFé mais conciso, masCASE WHENé o padrão SQL com melhor compatibilidade entre bancos de dados. Para condições complexas, use CASE; para verificações simples, use IF ou COALESCE.
P: Expressões CASE podem ser usadas em cláusulas WHERE? R: Sim, mas não é recomendado. Condições devem ser escritas diretamente no WHERE em vez de envolvidas em CASE. CASE é mais adequado para gerar novas colunas no SELECT, ordenação personalizada no ORDER BY e agregação condicional no GROUP BY.
P: Qual é a ordem de execução do CASE WHEN? R: CASE avalia cláusulas WHEN na ordem escrita — uma vez que uma condição WHEN é verdadeira, retorna o valor THEN correspondente e os WHENs subsequentes não são avaliados. Coloque as condições mais comuns ou de maior prioridade primeiro.
P: Qual é melhor, COALESCE ou IFNULL? R:
COALESCEé uma função padrão SQL que suporta múltiplos argumentos (ex:COALESCE(a, b, c, 0)) e funciona entre bancos de dados;IFNULLé específica do MySQL e suporta apenas dois argumentos.COALESCEé recomendada para melhor compatibilidade e flexibilidade.
📖 Resumo
CASE WHENé a expressão condicional do SQL e pode aparecer em SELECT, WHERE, ORDER BY, GROUP BY e mais- Simple CASE: comparação de igualdade, adequado para "um campo correspondendo a múltiplos valores"
- Searched CASE: condições arbitrárias, adequado para lógica complexa, recomendado como escolha padrão
- CASE no GROUP BY: combinado com SUM/COUNT para estatísticas condicionais (pivô de linhas para colunas), uma técnica central de análise de dados
- CASE no UPDATE: completa múltiplas operações de atualização em um único UPDATE
- IF/IFNULL/COALESCE: funções condicionais mais concisas; COALESCE tem a melhor compatibilidade
📝 Exercícios
Exercício 1 (⭐): Consulte todos os pedidos, adicionando uma coluna "faixa de valor": valor >= 3000 é "Pedido Grande", 1000-2999 é "Pedido Médio", < 1000 é "Pedido Pequeno". Ordene por faixa de valor.
Exercício 2 (⭐⭐): Agregue estatísticas de pedidos por funcionário usando CASE WHEN com funções de agregação para gerar um relatório com: nome do funcionário, total de pedidos, pedidos concluídos, pedidos pendentes e total de vendas.
Exercício 3 (⭐⭐): Use UPDATE + CASE para aumentar o salário em 10% para funcionários do departamento "Sales", 8% para o departamento "Technology", e 5% para outros departamentos.
Próxima Lição
👉 17-views-indexes - Visualizações e Índices: Aprenda como criar e usar visualizações (tabelas virtuais), bem como conceitos de índices e estratégias de otimização!



