Я пытаюсь решить эту конкретную проблему с PGExercises.com:Округление числа до ближайшего 10 в Postgres
https://www.pgexercises.com/questions/aggregates/rankmembers.html
Суть вопроса в том, что я дал таблица членов клуба и полчаса временных интервалов, которые они забронировали (получение списка - простая ВХОДНАЯ ВСТУПЛЕНИЕ из двух таблиц).
Я должен произвести нисходящее ранжирование участников по общего количества часов бронировали, округляется до ближайшего . Мне также нужно создать столбец с рангом, используя оконную функцию RANK()
и отсортировать результат по рангу. (Результат производит 30 записей.)
очень элегантное решение автора заключается в следующем:
select firstname, surname, hours, rank() over (order by hours) from
(select firstname, surname,
((sum(bks.slots)+5)/20)*10 as hours
from cd.bookings bks
inner join cd.members mems
on bks.memid = mems.memid
group by mems.memid
) as subq
order by rank, surname, firstname;
К сожалению, как SQL новичок, мое очень unelegant решение гораздо более запутанным, используя CASE WHEN
и преобразование чисел в текст для того, чтобы посмотреть на последнюю цифру для принятия решения о том, чтобы округлить до или вниз:
SELECT
firstname,
surname,
CASE
WHEN (SUBSTRING(ROUND(SUM(slots*0.5),0)::text from '.{1}$') IN ('5','6','7','8','9','0')) THEN CEIL(SUM(slots*0.5) /10) * 10
ELSE FLOOR(SUM(slots*0.5) /10) * 10
END AS hours,
RANK() OVER(ORDER BY CASE
WHEN (SUBSTRING(ROUND(SUM(slots*0.5),0)::text from '.{1}$') IN ('5','6','7','8','9','0')) THEN CEIL(SUM(slots*0.5) /10) * 10
ELSE FLOOR(SUM(slots*0.5) /10) * 10
END DESC) as rank
FROM cd.bookings JOIN cd.members
ON cd.bookings.memid = cd.members.memid
GROUP BY firstname, surname
ORDER BY rank, surname, firstname;
Тем не менее, мне удалось ALM ost получить его сразу - из 30 записей, я получаю один краевой кейс, чье имя - «Ponder» и фамилия - «Stephens». Его округленное количество часов составляет 124.5
, но решение настаивает на том, что округление его до ближайшего 10 должно привести к результату 120
, в то время как мое решение производит 130
.
(Кстати, есть несколько других примеры, такие как 204.5
округления до 210
как в шахте и решении при осуществлении автора.)
Что случилось с моим округлением логикой?
Это округление, а не ближайшее несколько, например. 'SELECT round (105/50 + .5) * 50' будет давать' 150' вместо '100'. – Gajus
@ Гаюс упс. Предполагалось, что это минус (не плюс). Исправлено, thx – Bohemian