Я знаю, что это старый пост, но хотел бы поделиться своим ответом. Это основано на ответе @hbrowser. Вот что я придумала. Это округляется вверх или вниз до ближайших 15 минут.
SELECT DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, GETDATE()) / 15.0, 0) * 15, 0);
Делая эту логику встроенной, а не внутри определенной пользователем функции, для больших наборов записей вы должны добиться большей производительности.
Вы можете изменить способ округления, переключив функцию ROUND
на FLOOR
или CAST expr AS INT
, чтобы всегда округлять, или используйте CEILING
, чтобы всегда округлять.
Ваш индивидуальный вариант использования определит, какой стиль округления вам может понадобиться.
Следующий скрипт может использоваться для наблюдения различий, предлагаемых различными методами округления:
ПРИМЕЧАНИЕ: чтобы упростить вывод, каждый результат был приведен к ВРЕМЕНИ (0), это делается только для упрощения вывода для этого конкретного примера.
DECLARE @SequenceStart SmallDateTime = CAST(GETDATE() AS Date);
DECLARE @SequenceEnd SmallDateTime = DateAdd(HOUR, 2, @SequenceStart); -- Recursive CTEs should always have an upper limit
DECLARE @SequenceIntMins INT = 5; -- increment by 5 to show the difference with rounding
WITH TimeSequence([Time]) as
(
SELECT @SequenceStart as [Time]
UNION ALL
SELECT DateAdd(MINUTE, 5, [Time]) FROM TimeSequence
WHERE [Time] <= @SequenceEnd
)
SELECT [Time] = Cast([Time] as TIME(0))
, Rounded = CAST(DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, [Time]) / 15.0, 0) * 15, 0) as TIME(0))
, Casted = CAST(DATEADD(MINUTE, CAST(DATEDIFF(MINUTE, 0, [Time]) / 15.0 AS INT) * 15, 0) as TIME(0))
, Floored = CAST(DATEADD(MINUTE, FLOOR(DATEDIFF(MINUTE, 0, [Time]) / 15.0) * 15, 0) as TIME(0))
, Ceilinged = CAST(DATEADD(MINUTE, CEILING(DATEDIFF(MINUTE, 0, [Time]) / 15.0) * 15, 0) as TIME(0))
FROM TimeSequence OPTION ( MaxRecursion 1000);
-- MaxRecursion may be neccessary if you change the interval or end of the sequence
Time Rounded Casted Floored Ceilinged
00:00:00 00:00:00 00:00:00 00:00:00 00:00:00
00:05:00 00:00:00 00:00:00 00:00:00 00:15:00
00:10:00 00:15:00 00:00:00 00:00:00 00:15:00
00:15:00 00:15:00 00:15:00 00:15:00 00:15:00
00:20:00 00:15:00 00:15:00 00:15:00 00:30:00
00:25:00 00:30:00 00:15:00 00:15:00 00:30:00
00:30:00 00:30:00 00:30:00 00:30:00 00:30:00
00:35:00 00:30:00 00:30:00 00:30:00 00:45:00
00:40:00 00:45:00 00:30:00 00:30:00 00:45:00
00:45:00 00:45:00 00:45:00 00:45:00 00:45:00
00:50:00 00:45:00 00:45:00 00:45:00 01:00:00
00:55:00 01:00:00 00:45:00 00:45:00 01:00:00
01:00:00 01:00:00 01:00:00 01:00:00 01:00:00
01:05:00 01:00:00 01:00:00 01:00:00 01:15:00