Час T-SQL округляється до найближчої хвилини та найближчих годин за допомогою функцій


113

У сервері SQL 2008 я хотів би округлити стовпець дати до найближчої години та найближчої хвилини, бажано, за допомогою існуючих функцій у 2008 році.

Для цього значення стовпця 2007-09-22 15:07:38.850вихід буде мати вигляд:

2007-09-22 15:08 -- nearest minute
2007-09-22 15    -- nearest hour

6
Чи не повинен приклад найближчої хвилини бути 15:08? Тому що секунд за хвилину - 60 ...
OMG Ponies

Ви навмисно не виправили цю помилку, коли ви редагували його питання, щоб ви могли зробити цей коментар?
Містер у середу,

@MrWed Wednesday Ви розумієте, що між редагуванням та коментарем існує більше 10 хвилин. Я б уявив, що думка виникла згодом.
лк.

Відповіді:


208
declare @dt datetime

set @dt = '09-22-2007 15:07:38.850'

select dateadd(mi, datediff(mi, 0, @dt), 0)
select dateadd(hour, datediff(hour, 0, @dt), 0)

повернеться

2007-09-22 15:07:00.000
2007-09-22 15:00:00.000

Вище сказане просто обрізає секунди та хвилини, створюючи результати, про які йдеться у запитанні. Як зазначав @OMG Ponies, якщо ви хочете округлити / вниз, то можете додати відповідно півхвилини або півгодини, а потім урізати:

select dateadd(mi, datediff(mi, 0, dateadd(s, 30, @dt)), 0)
select dateadd(hour, datediff(hour, 0, dateadd(mi, 30, @dt)), 0)

і ви отримаєте:

2007-09-22 15:08:00.000
2007-09-22 15:00:00.000

Перед тим, як тип даних про дату було додано в SQL Server 2008, я б використав описаний вище метод, щоб обрізати частину часу з дати, щоб отримати лише дату. Ідея полягає у визначенні кількості днів між відповідним датою та фіксованим моментом часу ( 0який неявно вражає 1900-01-01 00:00:00.000):

declare @days int
set @days = datediff(day, 0, @dt)

а потім додайте таку кількість днів до фіксованого моменту часу, який дає вам початкову дату із часом, встановленим на 00:00:00.000:

select dateadd(day, @days, 0)

або більш лаконічно:

select dateadd(day, datediff(day, 0, @dt), 0)

Використання іншої частини дати (наприклад hour, mi) буде працювати відповідно.


2
Я сумніваюсь, що хтось інший зіткнеться з цим, але якщо ви намагаєтесь округнути до найближчої секунди і додавши на 500 мілісекунд, вам захочеться зробити dateiff (другий, '1/1/2000', .... vs dateiff (по-друге, 0 .... тому що ви отримаєте помилку переповнення. Гадаю, секунди від 0 занадто великі.
Ерік Твілегар

"Додайте кількість годин з 1 січня 1900 року до 1 січня 1900 року" - я стикався з цим у Java / SQL, де це виглядає некрасиво. У моєму випадку це дійсно мало бути зроблено на стороні Java.
Corwin

Для обчислень з datetimeoffset, мені довелося замінити 0з , TODATETIMEOFFSET('1900-01-01 00:00:00', 0)щоб уникнути змушуючи місцевий часовий пояс на результат.
krlmlr

26

"Закруглена" вниз, як у вашому прикладі. Це поверне значення варчара дати.

DECLARE @date As DateTime2
SET @date = '2007-09-22 15:07:38.850'

SELECT CONVERT(VARCHAR(16), @date, 120) --2007-09-22 15:07
SELECT CONVERT(VARCHAR(13), @date, 120) --2007-09-22 15

Перетворити варчар назад у дату міг би зробити (за годину):CONVERT(datetime, CONVERT(VARCHAR(13), @date, 120)+':00:00')
Декула

10

Я усвідомлюю, що це питання давнє, і є прийнята і альтернативна відповідь. Я також усвідомлюю, що моя відповідь відповість лише на половину запитання, але для тих, хто хоче закрутитись до найближчої хвилини і все ще мати значення, сумісне з датою, використовуючи лише одну функцію :

CAST(YourValueHere as smalldatetime);

Години та секунди використовуйте відповідь Джеффа Огата (прийнята відповідь) вище.


1
Відмінна відповідь, я перевірив, що вона кругла, а не просто усічена. Для всіх, хто шукає цю опцію, smalldatetimeдодано в SQL 2008.
BradC

Це найкращий варіант, якщо вам потрібно зафіксувати деякі дані у таблиці, які вимагають лише часу на хвилину.
Шифрування

-1

Select convert(char(8), DATEADD(MINUTE, DATEDIFF(MINUTE, 0, getdate), 0), 108) as Time

буде округляти секунди до 00


Дуже повільно, і не округляється так, як просив ОП, а кружляє вниз, за ​​що він не просив. (Відмова від відповідальності - я вас не проголосував)
інженер, що повернувся,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.