Условия CASE WHEN
Конструкция case when выбирает значение из нескольких вариантов в зависимости от условий. Это аналог «если — иначе если — иначе».
Синтаксис
Заголовок раздела «Синтаксис»case when условие_1 then значение_1 when условие_2 then значение_2 ... else значение_по_умолчаниюendПравила работы
Заголовок раздела «Правила работы»- Условия проверяются сверху вниз
- Срабатывает первое истинное условие — остальные не проверяются
- Если ни одно условие не истинно, возвращается значение из
else - Если
elseотсутствует — возвращаетсяnull - Все возвращаемые значения должны быть одного типа (нельзя в одной ветке вернуть строку, в другой число)
- Конструкция обязательно завершается словом
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 falseendРезультат — логическое значение. На такую колонку дальше ссылаются прямо в условии, без сравнения:
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.0endРезультат — стоимость переработки тонны, её остаётся умножить на 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Вложенный case
Заголовок раздела «Вложенный case»В качестве значения ветки 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 со значением
Заголовок раздела «Короткая форма: case со значением»Если все условия — это сравнение одной и той же колонки с разными значениями, можно записать короче:
case rock when 'oxide' then 12.5 when 'sulphide' then 18.0 when 'mixed' then 15.0 else 0.0endЭто эквивалент 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.