Menu

CASE no SQLite: WHEN, THEN, ELSE e IIF

Como o CASE funciona no SQLite — formas simples e pesquisada, uso em SELECT, ORDER BY e WHERE, e quando vale mais usar IIF.

Esta página tem editores executáveis — edite, execute e veja a saída na hora.

CASE é o If/Else do SQL

O CASE é como você coloca lógica condicional dentro de uma query no SQLite. Ele percorre os ramos WHEN na ordem, escolhe o primeiro que casar e devolve o valor que vem depois do THEN. Se nada casar, retorna o valor do ELSE — ou NULL, caso você não tenha escrito um.

A palavra-chave aqui é expressão. O CASE produz um valor, então ele cabe em qualquer lugar onde um valor é aceito: uma coluna do SELECT, uma chave do ORDER BY, o lado direito de uma comparação ou até como argumento de uma função.

Esse é o esqueleto: CASE, um ou mais WHEN ... THEN ..., um ELSE opcional e fecha com END. O END é obrigatório — esquecer dele é o erro de digitação mais comum aqui.

Um exemplo prático de CASE WHEN no SQLite

Imagine que você tem uma tabela de pedidos e quer classificar cada linha pelo tamanho. Vamos montar uma rapidinho ali na hora pra você poder rodar a query:

Os ramos são avaliados de cima para baixo. O primeiro que casar vence, então ordene do mais específico para o mais genérico. O ELSE funciona como uma rede de segurança, capturando tudo o que não bateu — sem ele, 1200.00 voltaria como NULL em vez de 'grande'.

Diferença entre CASE simples e pesquisado no SQLite

O exemplo acima usa a forma pesquisada (searched): cada WHEN carrega sua própria condição booleana. Quando você só precisa comparar uma mesma expressão com vários valores fixos, dá para encurtar usando a forma simples:

A expressão depois do CASE é avaliada uma vez e comparada com = contra cada valor de WHEN. Fica mais limpo quando você está fazendo comparações de igualdade em uma única coluna.

Tem um detalhe importante: o CASE simples usa =, e NULL = NULL não é verdadeiro em SQL. Se status puder ser NULL, os ramos 'A'/'B'/'C' não vão casar com ele — vai cair no ELSE. Para tratar NULL de forma explícita, mude para a forma pesquisada e use WHEN status IS NULL THEN ....

CASE dentro de ORDER BY no SQLite

O ORDER BY aceita qualquer expressão, então o CASE funciona tranquilamente ali. É útil quando você quer uma ordenação personalizada que não segue ordem alfabética nem numérica:

'high' < 'low' < 'medium' na ordem alfabética, o que não serve pra nada quando você precisa priorizar tarefas. Mapeando cada prioridade para um número com CASE, você consegue a ordem que realmente faz sentido. O , id no final serve como critério de desempate estável.

CASE dentro do WHERE no SQLite

Dá pra usar CASE dentro do WHERE, mas, na maioria das vezes, não compensa — encadear AND/OR fica bem mais legível. Onde ele realmente brilha é quando a própria condição depende de outro valor:

Itens em promoção entram com preço abaixo de 20; os demais, abaixo de 30. Ou seja, o próprio limite muda conforme a condição. Sem o CASE, você teria que escrever algo como (on_sale = 1 AND price < 20) OR (on_sale = 0 AND price < 30) — dá no mesmo, mas polui a consulta.

CASE dentro de funções de agregação

É aqui que o CASE realmente brilha. Combinando com SUM ou COUNT, dá pra calcular totais de um subconjunto de linhas numa única varredura — é o jeito SQL de dizer "conta quantas atendem a essa condição":

O CASE devolve 1 para as linhas que batem com a condição e 0 para o resto, então o SUM acaba virando uma contagem condicional. Esse mesmo truque funciona para faturamento — basta retornar total nas linhas que se encaixam e 0 nas demais. Uma única varredura na tabela e você já consegue várias agregações condicionais.

IIF: o atalho de duas saídas

Quando você tem uma única condição com apenas dois resultados possíveis, o SQLite oferece o IIF(cond, when_true, when_false). É só um açúcar sintático para CASE WHEN cond THEN when_true ELSE when_false END:

Use IIF quando a lógica for binária e fizer mais sentido em uma única linha. Já o CASE entra em cena quando você tem três ou mais ramificações, precisa tratar NULL separadamente ou quer aproveitar a ordem de avaliação das várias cláusulas WHEN.

Armadilhas que vale conhecer

Algumas coisas costumam pegar a galera de surpresa:

  • Esquecer o END. O CASE abre um bloco e o END fecha. O SQLite só vai acusar o erro de parsing bem depois do ponto onde você realmente errou.
  • Sem ELSE, o resultado é NULL. Se nenhuma das ramificações WHEN casar e você não colocou ELSE, sobra NULL. Às vezes é isso que você quer mesmo, mas na maioria das vezes não é.
  • A ordem das ramificações importa. Na forma pesquisada, o primeiro WHEN que bater vence. Colocar WHEN total < 500 antes de WHEN total < 100 faz a segunda condição nunca ser alcançada.
  • Mistura de tipos. Cada ramificação pode devolver um tipo diferente e o SQLite não vai reclamar — mas o código que consome o resultado pode reclamar. Procure manter tipos compatíveis em todos os ramos (tudo texto, tudo numérico).
  • CASE simples e NULL. Como já comentamos: a forma simples usa =, que nunca casa com NULL. Quando tiver nulos em jogo, vá de forma pesquisada.

A seguir: funções de string

O CASE permite ramificar a partir de valores; o próximo capítulo começa a parte de transformar valores. As funções de string — UPPER, LOWER, SUBSTR, REPLACE e os padrões com LIKE — cuidam do trabalho do dia a dia de limpar e reformatar colunas de texto. É o que vem na sequência.

Perguntas frequentes

O que é uma expressão CASE no SQLite?

O CASE é a versão SQL do if/else: ele avalia condições e devolve um valor. Repare que é uma expressão, não um comando — ou seja, dá pra usar em qualquer lugar onde um valor é aceito: no SELECT, no WHERE, no ORDER BY, num UPDATE e até dentro de funções de agregação. Cada ramo segue o formato WHEN condição THEN valor, com um ELSE opcional no final.

Qual a diferença entre CASE simples e CASE pesquisado no SQLite?

O CASE simples compara uma única expressão com vários valores: CASE status WHEN 'A' THEN ... WHEN 'B' THEN ... END. Já o CASE pesquisado avalia uma condição booleana independente em cada ramo: CASE WHEN price > 100 THEN ... WHEN qty = 0 THEN ... END. A forma pesquisada é mais flexível — você mistura colunas, operadores e checagens de NULL à vontade.

Quando devo usar IIF em vez de CASE no SQLite?

IIF(cond, a, b) nada mais é que um atalho para CASE WHEN cond THEN a ELSE b END. Use IIF quando a lógica tem só dois caminhos e fica mais legível assim. Parta para o CASE quando tiver três ou mais ramos, quiser aproveitar a ordem de avaliação dos WHEN ou precisar tratar NULL explicitamente com WHEN col IS NULL.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR