Вложенность CASE WHEN в SQL

ВЛОЖЕННОСТЬ CASE WHEN 

Бывают кейсы, когда нам нужно прописывать условное выражение по нескольким признакам. В этом случае сложность условных выражений повышается, и появляется потребность создавать вложенные CASE WHEN конструкции.

Давайте рассмотрим пример.

Представим, что мы, помимо рейтинга, еще учитываем возраст футболиста для определения его класса. Допустим, что если футболист моложе 30 лет, то мы оцениваем его класс по стандартной шкале: 

  • overall от 85 это ‘Top’;
  • overall от 80 до 84 это ‘Good’;
  • overall от 75 до 79 это ‘Average’;
  • overall ниже 75 это ‘Bad’.

А если старше 30, то нам нужно на 5 пунктов больше, чтобы у футболиста был такой же рейтинг:

  • overall от 90 это ‘Top’;
  • overall от 85 до 89 это ‘Good’;
  • overall от 80 до 85 это ‘Average’;
  • overall ниже 80 это ‘Bad’.

Эту задачу мы можем решить большим количеством условий:

select
    long_name,
    club,
    case
        when age < 30 and overall >= 85 then 'Top' 
        when age < 30 and overall between 80 and 84 then 'Good'
        when age < 30 and overall between 75 and 79 then 'Average'
        when age < 30 and overall < 75 then 'Bad'
        when age >= 30 and overall >= 90 then 'Top' 
        when age >= 30 and overall between 85 and 89 then 'Good'
        when age >= 30 and overall between 80 and 84 then 'Average'
        else 'Bad'
    end rating_class
from
    fifa_players_2018

Согласитесь, написано тяжело и легко допустить ошибку. С помощью вложенных условных выражений это написано намного проще:

select
    long_name,
    club,
    case
        when age < 30 then (
            case
                when overall >= 85 then 'Top'
                when overall between 80 and 84 then 'Good'
                when overall between 75 and 79 then 'Average'
                else 'Bad'
            end)
        else (
            case 
                when overall >= 90 then 'Top' 
                when overall between 85 and 89 then 'Good'
                when overall between 80 and 84 then 'Average'
                else 'Bad'
            end)
        end rating_class
from
    fifa_players_2018

По сути, мы разделили CASE WHEN на два условия по возрасту, и внутри большого условия расписали варианты через тот же CASE WHEN. Так каждый уровень логики читается отдельно, что упрощает поддержку кода

Нужно обратить внимание, что во вложенном CASE WHEN мы прописываем END, но после него не обозначаем никакую колонку. Всегда, когда CASE WHEN  выражение будет преобразовываться, колонку после END писать не нужно.