Перейти к содержимому

Условия CASE WHEN

Конструкция case when выбирает значение из нескольких вариантов в зависимости от условий. Это аналог «если — иначе если — иначе».

case
when условие_1 then значение_1
when условие_2 then значение_2
...
else значение_по_умолчанию
end
  1. Условия проверяются сверху вниз
  2. Срабатывает первое истинное условие — остальные не проверяются
  3. Если ни одно условие не истинно, возвращается значение из else
  4. Если else отсутствует — возвращается null
  5. Все возвращаемые значения должны быть одного типа (нельзя в одной ветке вернуть строку, в другой число)
  6. Конструкция обязательно завершается словом end

Простой пример: классификация по содержанию

Заголовок раздела «Простой пример: классификация по содержанию»
case
when grade >= 1.0 then 'high_grade'
when grade >= 0.5 then 'medium_grade'
when grade >= 0.2 then 'low_grade'
else 'waste'
end

Порядок ветвей важен. Если переставить ветви в обратном порядке, всё попадёт в low_grade, потому что 0.2 срабатывает и для значений выше 1.0.

case
when grade >= $cutoff_grade and sort <> 0 then true
else false
end

Результат — логическое значение. На такую колонку дальше ссылаются прямо в условии, без сравнения:

case when is_ore then $processing_ore * tonnage else 0 end

Пример: удельная стоимость переработки по типу руды

Заголовок раздела «Пример: удельная стоимость переработки по типу руды»
case
when rock = 'oxide' then 12.5
when rock = 'sulphide' then 18.0
when rock = 'mixed' then 15.0
else 0.0
end

Результат — стоимость переработки тонны, её остаётся умножить на tonnage.

case
when zc >= 400 and rock = 'ore' then 'top_ore'
when zc >= 200 and rock = 'ore' then 'mid_ore'
when rock = 'ore' then 'deep_ore'
else 'non_ore'
end

В качестве значения ветки then можно использовать ещё один case:

case
when rock = 'ore' then
case
when grade >= 1.0 then 'ore_high'
when grade >= 0.3 then 'ore_low'
else 'ore_subgrade'
end
else 'waste'
end

То же самое часто короче пишется одним уровнем, если условия можно склеить через and.

Если все условия — это сравнение одной и той же колонки с разными значениями, можно записать короче:

case rock
when 'oxide' then 12.5
when 'sulphide' then 18.0
when 'mixed' then 15.0
else 0.0
end

Это эквивалент when rock = 'oxide' then ....

Пропущен end — выражение не сработает:

case when grade > 0.5 then 1 else 0 -- ОШИБКА
case when grade > 0.5 then 1 else 0 end -- правильно

Разные типы в ветвях — Pitlord не сможет определить тип результирующей колонки:

case when grade > 0.5 then 1 else 'low' end -- ОШИБКА: число и строка
case when grade > 0.5 then 1 else 0 end -- правильно: только числа

Сравнение с NULL через = — всегда даёт NULL, ветка не сработает. Нужен is null:

case when grade is null then 0 else grade end -- правильно
case when grade = null then 0 else grade end -- НЕ работает

Подробнее — в Работа с NULL.