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.

SQL
CASE expressao
    WHEN valor1 THEN resultado1
    WHEN valor2 THEN resultado2
    ...
    ELSE resultado_padrao
END
SQL
-- 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.

SQL
CASE
    WHEN condicao1 THEN resultado1
    WHEN condicao2 THEN resultado2
    ...
    ELSE resultado_padrao
END
SQL
-- 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;
💡 Simple CASE vs Searched CASE: Simple CASE só pode fazer comparações de igualdade; searched CASE pode usar >, <, 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.

SQL
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".

SQL
-- 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.

SQL
-- 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.

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
SQL
-- 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 vs IFNULL: 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

SQL
-- 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
💡 Dica: Expressões CASE retornam um valor e podem aparecer em qualquer lugar onde uma expressão é usada (SELECT, WHERE, ORDER BY, GROUP BY, etc.). Cláusulas WHEN são avaliadas em ordem — uma vez que uma correspondência é encontrada, o resultado é retornado e os WHENs subsequentes não são avaliados.

💡 Dica: Se ELSE for omitido e nenhuma correspondência for encontrada, CASE retorna NULL. Recomenda-se sempre incluir ELSE para lidar com casos inesperados.

Sintaxe de Funções Condicionais

SQL
IF(condicao, valor_verdadeiro, valor_falso)
IFNULL(expressao, substituicao)
COALESCE(valor1, valor2, ..., valorN)
💡 Dica: COALESCE pode substituir IFNULL e suporta múltiplos valores de fallback — é recomendada.


Exemplo: Adicionar Rótulos de Status e Prioridade aos Pedidos (Dificuldade ⭐)

SQL
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;
▶ Experimente

Saída:

TEXT
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:

  1. O primeiro CASE converte status em inglês para descrições com rótulos
  2. O segundo CASE classifica a prioridade pelo valor
  3. O CASE no ORDER BY ordena por prioridade

Exemplo: Contar Funcionários por Nível Salarial por Departamento (Dificuldade ⭐⭐)

SQL
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;
▶ Experimente

Saída:

TEXT
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:

  1. GROUP BY agrupa por departamento
  2. Cada SUM(CASE ...) conta funcionários que atendem à condição, alcançando pivô de linhas para colunas
  3. 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

SQL
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:

TEXT
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
💡 Abordagem: As cláusulas WHEN do searched CASE são avaliadas em ordem — uma vez que uma correspondência é encontrada, retorna imediatamente, então a ordem das condições importa — condições mais específicas devem vir primeiro.

Cenário 2: UPDATE + CASE para Atualizações Condicionais em Lote

SQL
-- 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;
💡 Abordagem: Um único UPDATE completa múltiplas operações de lógica de atualização, evitando escrever múltiplas instruções UPDATE. CASE avalia em ordem, então a condição "departamento de Tecnologia e contratação antecipada" vem antes de "departamento de Tecnologia".


❓ Perguntas Frequentes

P: Qual a diferença entre CASE WHEN e IF? Qual devo usar? R: IF só pode lidar com escolhas binárias (verdadeiro/falso) e é adequado para cenários simples; CASE WHEN pode lidar com múltiplos ramos de condições e é adequado para lógica complexa. No MySQL, IF é mais conciso, mas CASE 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


📝 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!

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%