CodeGym /Cursos /SQL SELF /Expressões condicionais: CASE WHEN ... THEN ... ELSE ... ...

Expressões condicionais: CASE WHEN ... THEN ... ELSE ... END

SQL SELF
Nível 10, Lição 0
Disponível

Provavelmente você já trombou com expressões condicionais em linguagens de programação: if-else, switch-case e essas paradas. No SQL tem sua própria ferramenta pra lidar com condições: é a expressão CASE. Ela deixa você tomar decisões direto na query: se a condição bate, faz uma coisa, se não bate — faz outra.

A estrutura CASE é especialmente útil quando você precisa lidar com dados que podem ter valores NULL. O sintaxe é simples, tipo cola de prova, olha só:

CASE
    WHEN condição1 THEN resultado1
    WHEN condição2 THEN resultado2
    ...
    ELSE resultado_padrao
END

Parece lógico, né? "Se for assim, faz isso, senão faz aquilo". Fácil de lembrar: "WHEN — é o se, THEN — é o que fazer, ELSE — é o que fazer se nada encaixar".

Exemplo: classificação de produtos

Imagina que a gente tem uma tabela products, com uma coluna price, e queremos separar os produtos em grupos de acordo com o preço.

id name price
1 Magic Wand 120
2 Potion Set 45
3 Crystal Ball 75
4 Enchanted Map NULL
5 Broomstick 99
6 Spell Book 180
SELECT
    name AS product_name,
    price,
    CASE
        WHEN price IS NULL THEN 'Desconhecido'
        WHEN price < 50 THEN 'Econômico'
        WHEN price BETWEEN 50 AND 100 THEN 'Padrão'
        ELSE 'Premium'
    END AS price_category
FROM products;

O que tá rolando aqui?

  1. Se o preço price do produto não tá informado NULL, a gente mostra a categoria como 'Desconhecido'.
  2. Se o preço for menor que 50, o produto é considerado econômico 'Econômico'.
  3. Se o preço tá entre 50 e 100, ele cai na categoria 'Padrão'.
  4. O resto — é produto premium 'Premium'.

Olha o resultado:

product_name price price_category
Magic Wand 120 Premium
Potion Set 45 Econômico
Crystal Ball 75 Padrão
Enchanted Map NULL Desconhecido
Broomstick 99 Padrão
Spell Book 180 Premium

O SQL, tipo um mago, lê as linhas da tabela products, aplica em cada uma e classifica de boa.

Trabalhando com NULL no CASE WHEN

Direto rola de ter valores faltando nos dados (salve, NULL), e aí tem que substituir por alguma coisa. Por exemplo, temos uma tabela users com a coluna email, e pros usuários sem email queremos mostrar 'Não informado'.

user_id name email
1 Alex Lin alex@example.com
2 Maria Chi NULL
3 Anna Song anna@magic.com
4 Otto Art NULL
5 John Smith john@wizard.org
SELECT
    user_id,
    name,
    CASE
        WHEN email IS NULL THEN 'Não informado'
        ELSE email
    END AS email_address
FROM users;
user_id name email_address
1 Alex Lin alex@example.com
2 Maria Chi Não informado
3 Anna Song anna@magic.com
4 Otto Art Não informado
5 John Smith john@wizard.org

O SQL aqui age tipo um xamã, dando vida pras linhas meio vazias. Se não tem email, ele troca por 'Não informado'. Se tem — só mostra mesmo.

Expressões condicionais com números

Às vezes não é só trocar valores, mas criar uma lógica nova. Por exemplo, imagina uma tabela students com as colunas score (nota) e name.

name score
Alex Lin 95
Maria Chi 82
Anna Song 48
Otto Art NULL
John Smith 67
Zoe Black 30

A gente quer avaliar os estudantes como "Excelente", "Passou" e "Reprovado", dependendo da nota deles.

SELECT
    name AS student_name,
    score,
    CASE
        WHEN score IS NULL THEN 'Sem Nota'
        WHEN score >= 90 THEN 'Excelente'
        WHEN score >= 50 THEN 'Passou'
        ELSE 'Reprovado'
    END AS performance_category
FROM students;
student_name score performance_category
Alex Lin 95 Excelente
Maria Chi 82 Passou
Anna Song 48 Reprovado
Otto Art NULL Sem Nota
John Smith 67 Passou
Zoe Black 30 Reprovado

O SQL distribui os estudantes, tipo um examinador rígido: 90 pontos ou mais — só "Excelente", de 50 pra cima — "Passou". Se não bate a nota... já era.

Agrupamento e tratamento de NULL

Trabalhar com grupos de dados é outro lugar onde CASE WHEN brilha. Imagina que temos uma tabela orders, e queremos contar o total de pedidos por status, incluindo os que têm status NULL.

order_id status
1 Completed
2 Pending
3 NULL
4 Shipped
5 Completed
6 NULL
7 Pending
8 Completed
9 Shipped
10 NULL
SELECT
    CASE
        WHEN status IS NULL THEN 'Sem Status'
        ELSE status
    END AS order_status,
    COUNT(*)
FROM orders
GROUP BY 
    CASE
        WHEN status IS NULL THEN 'Sem Status'
        ELSE status
    END;

Essa query trata direitinho os status NULL e coloca 'Sem Status' no lugar, além de contar o total de pedidos em cada grupo. Olha o resultado:

order_status count
Completed 3
Pending 2
Shipped 2
Sem Status 3

Casos práticos: "Truques" com CASE WHEN

Exemplo 1: Ordenação considerando NULL

Às vezes você quer mostrar valores NULL primeiro ou por último numa lista ordenada. Isso é comum, tipo em listas de tarefas, onde as tarefas prioritárias aparecem no topo e as sem prioridade (NULL) ficam no fim.

task_id task_name priority
1 Fix bugs 1
2 Update documentation 3
3 Plan sprint NULL
4 Code review 2
5 Organize meeting NULL
6 Deploy release 1
SELECT
    task_name,
    priority,
    CASE
        WHEN priority IS NULL THEN 1
        ELSE 0
    END AS priority_sort
FROM tasks
ORDER BY priority_sort ASC, priority ASC;

Aqui a gente criou uma coluna "virtual" priority_sort, que joga os NULL lá pra baixo, e o resto ordena do menor pro maior.

task_name priority priority_sort
Deploy release 1 0
Fix bugs 1 0
Code review 2 0
Update documentation 3 0
Plan sprint NULL 1
Organize meeting NULL 1

Exemplo 2: Cálculos considerando NULL

Agora imagina que a gente tá calculando o valor final do pedido na tabela orders, onde a coluna discount pode ser NULL se não tiver desconto.

order_id total_price discount
101 100 10
102 200 NULL
103 150 15
104 120 NULL
105 80 5

A gente precisa trocar NULL por 0, pra não quebrar a conta.

SELECT 
    order_id,
    total_price,
    discount,
    total_price - 
    CASE
        WHEN discount IS NULL THEN 0
        ELSE discount
    END AS final_price
FROM orders;
order_id total_price discount final_price
101 100 10 90
102 200 NULL 200
103 150 15 135
104 120 NULL 120
105 80 5 75

Esse truque mágico com CASE garante que NULL não vai ferrar seus cálculos.

Pra orderid = 101: discount = 10. finalprice = 100 - 10 = 90. Pra orderid = 102: discount = NULL. CASE retorna 0. finalprice = 200 - 0 = 200. Pra orderid = 103: discount = 15. finalprice = 150 - 15 = 135. Pra orderid = 104: discount = NULL. CASE retorna 0. finalprice = 120 - 0 = 120. Pra orderid = 105: discount = 5. finalprice = 80 - 5 = 75.

Exemplo 3: Mostrando status customizado do usuário

No dia a dia rola de mostrar o status do usuário (tipo "Ativo" ou "Esperando") ou avisar que não tem dado. Por exemplo, na tabela users tem a coluna last_login, que guarda a data do último login.

user_id name last_login
1 Alex Lin 2024-12-10
2 Maria Chi 2025-04-20
3 Anna Song NULL
4 Otto Art 2025-05-01
5 Liam Park 2025-05-25
SELECT
    user_id,
    name,
    CASE
        WHEN last_login IS NULL THEN 'Nunca entrou'
        WHEN last_login < CURRENT_DATE - INTERVAL '30 days' THEN 'Inativo'
        ELSE 'Ativo'
    END AS user_status
FROM users;

Com essa query o sistema do admin ganha vida: usuários sem login são chamados de "Nunca entrou", quem não entra faz tempo é "Inativo". O resto tá ativo!

user_id name user_status
1 Alex Lin Inativo
2 Maria Chi Inativo
3 Anna Song Nunca entrou
4 Otto Art Inativo
5 Liam Park Ativo

Erros comuns e como evitar

Esquecer o ELSE: Se você não colocar ELSE, o SQL só vai retornar NULL se nenhuma condição bater. Nem sempre é o que você quer. Então é melhor sempre colocar ELSE, mesmo se acha que cobriu tudo.

CASE
    WHEN condição THEN resultado
    -- ELSE 'Valor padrão' -- não esquece!
END

Condições complicadas sem parênteses: Se tiver várias condições com AND, OR ou NOT, sempre usa parênteses. Sem eles, sua query pode "pensar" errado.

CASE
    WHEN (column1 IS NOT NULL AND column2 > 5) THEN 'Válido'
    ELSE 'Inválido'
END

Trabalhando com NULL: Lembra que NULL nunca é igual (=) a nada. Por exemplo:

CASE
    WHEN column = NULL THEN 'Nope!' -- Errado!
    WHEN column IS NULL THEN 'Correto!' -- Assim que faz.
END
2
Tarefa
SQL SELF, nível 10, lição 0
Bloqueado
Exibição condicional de dados ausentes
Exibição condicional de dados ausentes
2
Tarefa
SQL SELF, nível 10, lição 0
Bloqueado
Atribuição de categorias com base em valores numéricos
Atribuição de categorias com base em valores numéricos
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION