Собесов

CASE WHEN: преобразовать балл в оценку

SQLУсловные выраженияЛёгкаяJunior

Условие

Дана таблица Test(Student_ID, Student_Name, Result). Напишите запрос, который по баллу Result выводит оценку Mark:

  • 8–10 → отлично
  • 5–7 → хорошо
  • 3–4 → удовлетворительно
  • 1–2 → неудовлетворительно

Решение

SELECT Student_ID,
       Student_Name,
       Result,
       CASE
         WHEN Result BETWEEN 8 AND 10 THEN 'отлично'
         WHEN Result BETWEEN 5 AND 7  THEN 'хорошо'
         WHEN Result BETWEEN 3 AND 4  THEN 'удовлетворительно'
         WHEN Result BETWEEN 1 AND 2  THEN 'неудовлетворительно'
       END AS Mark
FROM   Test;

Два синтаксиса CASE

-- 1) Searched CASE — произвольные условия
CASE WHEN x > 5 THEN 'big'
     WHEN x = 5 THEN 'mid'
     ELSE 'small'
END
 
-- 2) Simple CASE — сравнение со значением
CASE x
  WHEN 5 THEN 'mid'
  WHEN 10 THEN 'top'
  ELSE 'other'
END

Что вернёт CASE без ELSE

Если ни одно условие не выполнено и нет ELSE — вернётся NULL. Это частый источник багов: «куда делись строки?» — на самом деле они не делись, в Mark просто NULL.

-- Result = 11 не попадает ни под одно условие → Mark = NULL

Альтернатива без CASE

В PostgreSQL можно через NUMRANGE или WIDTH_BUCKET:

SELECT Student_ID,
       (ARRAY['неудовлетворительно','удовлетворительно','хорошо','отлично'])
       [WIDTH_BUCKET(Result, ARRAY[1, 3, 5, 8])] AS Mark
FROM Test;

Подводные камни

  1. Порядок WHEN важен — выполняется первое сработавшее условие, остальные игнорируются. Если поставить WHEN Result > 0 THEN ... первым, всё провалится в него.
  2. BETWEEN включает границыBETWEEN 8 AND 10 это [8, 10]. Если в данных 8.5 — попадёт сюда.
  3. Без ELSENULL для непокрытых случаев. Лучше явно прописать ELSE.
  4. CASE в WHERE / GROUP BY — работает, но часто яснее переписать через простые условия.

Эталонный ответ

SELECT Student_ID, Student_Name, Result,
       CASE
         WHEN Result BETWEEN 8 AND 10 THEN 'отлично'
         WHEN Result BETWEEN 5 AND 7  THEN 'хорошо'
         WHEN Result BETWEEN 3 AND 4  THEN 'удовлетворительно'
         ELSE 'неудовлетворительно'
       END AS Mark
FROM Test;

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти