Transact-SQL имеет функцию, аналогичную функции MS Logparser Quantize?

Если вы знакомы с Microsoft Log Parser, вы, вероятно, узнаете функцию Quantize, которая усекает значение до ближайшего кратного другого значения. Это очень удобно для группировки полей даты и времени в приращениях.

Date-Time              Count
1/1/2010 00:00         100
1/1/2010 00:15         134
1/1/2010 00:30         56
....

Я пытаюсь найти аналогичную функцию в Transaction-SQL (в частности, SQL Server 2005 или 2008), которая позволит мне выполнить аналогичную группировку по дате и времени.

2 ответа

Решение

Не напрямую, это не так. Но вы можете сгруппировать по функции (которую вы пишете), которая округляет столбец datetime до ближайшего четверти часа (или что бы ни делал Quantize).

SELECT
    dbo.QuarterHour(DateColumn) AS Date-Time
  , COUNT(*) AS Count
FROM MyTable
GROUP BY dbo.QuarterHour(DateColumn)

Вы можете округлить до любого заданного количества минут следующим образом:

DateAdd(Minute, (DateDiff(minute, 0, getutcdate() )/15) * 15, 0)

Вместо того, чтобы использовать getutcdate() Вы можете использовать свой столбец даты, переменную или выражение. Кроме того, количество минут может быть переменной.

declare @minutesQuantize int set @minutesQuantize = 15
DateAdd(Minute, (DateDiff(minute, 0, getutcdate() )/@minutesQuantize) * @minutesQuantize, 0)

Единственное правило заключается в том, что разница в дате должна вписываться в целое число, то есть быть менее 2 миллиардов. Это означает, что вы не можете делать секунды или миллисекунды без более сложного выражения.

Если вам нужны секунды или миллисекунды, сделайте это:

dateadd(ms, (datediff(ms, dateadd(day, datediff(day, 0, @date), 0), @date)/@msInterval)*@msInterval, dateadd(day, datediff(day, 0, @date), 0))

Или, если вы хотите обернуть это в функцию:

create function dbo.DateRoundMinutes(@dt datetime, @minutes int)
returns datetime
as  begin
return  DateAdd(Minute, (DateDiff(minute, 0, @dt )/@minutes) * @minutes, 0)
end

go
create function dbo.DateRoundMilliseconds(@dt datetime, @ms int)
returns datetime
as begin
 return dateadd(ms, (datediff(ms, dateadd(day, datediff(day, 0, @dt), 0), @dt)/@ms)*@ms, dateadd(day, datediff(day, 0, @dt), 0))
end

Который вы можете использовать так:

select t.dt, 
dbo.DateRoundMilliseconds(dt, 500) dt0_5Second, -- Half second
dbo.DateRoundMilliseconds(dt, 5000) dt5second,  -- 5 second
dbo.DateRoundMilliseconds(dt, 15000) dt15Second,
dbo.DateRoundMilliseconds(dt, 90000) dt90Second,
dbo.DateRoundMinutes(dt, 2) dt2Minute,
dbo.DateRoundMinutes(dt, 5) dt5Minute,
dbo.DateRoundMinutes(dt, 15) dt15Minute,
dbo.DateRoundMinutes(dt, 90) dt90Minute
from
        /* some table having a column dt */
Другие вопросы по тегам