Proposta de site feita pela Genesis Innovation · conteúdo do LinkedIn de Daniel Santos

Pular para o conteúdo
Daniel Santos

Wiki SQL

CASE, agregação condicional e pivot

CASE é o if do SQL. Dentro de um SUM, vira colunas por categoria sem precisar de PIVOT.

CASE WHEN … THEN … ELSE … END devolve um valor conforme a primeira condição verdadeira. Sem ELSE, o que não casa vira NULL.

SQL · SQLite
SELECT id, valor,
       CASE WHEN valor IS NULL THEN 'sem valor'
            WHEN valor >= 500 THEN 'alto'
            WHEN valor >= 100 THEN 'médio'
            ELSE 'baixo' END AS faixa
FROM pedidos
WHERE id BETWEEN 104 AND 107
ORDER BY id;

Saída

id  | valor | faixa
--- | ----- | ---------
104 | 180   | médio
105 | 1050  | alto
106 | NULL  | sem valor
107 | 30    | baixo

A ordem das condições importa: valor >= 100 também é verdade para 1050, mas a primeira que casa vence.

Agregação condicional: colunas por status

Somar um CASE conta ou soma só o que interessa, numa passada só pela tabela. É o "pivot" portátil, que roda em qualquer banco.

SQL · SQLite
SELECT data,
       SUM(CASE WHEN status = 'entregue' THEN 1 ELSE 0 END) AS entregues,
       SUM(CASE WHEN status = 'cancelado' THEN 1 ELSE 0 END) AS cancelados,
       SUM(CASE WHEN status = 'pendente' THEN 1 ELSE 0 END) AS pendentes
FROM pedidos
GROUP BY data
ORDER BY data;

Saída

data       | entregues | cancelados | pendentes
---------- | --------- | ---------- | ---------
2024-06-01 | 2         | 0          | 0
2024-06-02 | 1         | 1          | 0
2024-06-03 | 1         | 0          | 1
2024-06-04 | 2         | 0          | 0
2024-06-05 | 2         | 0          | 0

Taxa com o denominador certo

SQL · SQLite
SELECT ROUND(100.0 * SUM(CASE WHEN status = 'cancelado' THEN 1 ELSE 0 END) / COUNT(*), 1) AS pct_cancelados,
       10 / 4 AS divisao_inteira,
       10 / 4.0 AS divisao_real
FROM pedidos;

Saída

pct_cancelados | divisao_inteira | divisao_real
-------------- | --------------- | ------------
10             | 2               | 2.5

Inteiro dividido por inteiro dá inteiro no SQLite e no PostgreSQL. Multiplique por 100.0 (ou converta com CAST) antes de dividir. No Spark SQL, / sempre devolve fracionário; a divisão inteira é div.

  • No Spark e no Databricks existe PIVOT (SUM(valor) FOR status IN ('entregue', 'cancelado')), e no PySpark groupBy("data").pivot("status").sum("valor"). Passar a lista de valores evita uma leitura extra só para descobrir as colunas.

Fontes

Conhecimento compartilhado pela Genesis Innovation.