Условие
Дана таблица 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;Подводные камни
- Порядок WHEN важен — выполняется первое сработавшее условие, остальные игнорируются. Если поставить
WHEN Result > 0 THEN ...первым, всё провалится в него. BETWEENвключает границы —BETWEEN 8 AND 10это[8, 10]. Если в данных8.5— попадёт сюда.- Без
ELSE→NULLдля непокрытых случаев. Лучше явно прописатьELSE. 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;