在SQL SERVER中如何按时间间隔分组?
为了节省时间我已经提出了这个解决方案,对我而言,它的效果非常好。您可以生成任何时基,然后按任意间隔分组。非常适合做时间加权平均值。如果有人有更好的方法,我很乐意听取你的意见。
小时
declare @startdate datetime2
declare @enddate datetime2
declare @interval int
set @startdate = '2017-01-01 00:00:00'
set @enddate = '2017-01-31 00:00:00'
set @interval = 4 --Group by Every 4 hours
;with
ALL_INTERVALS
AS (
SELECT TOP (DATEDIFF(HOUR,@startdate,@enddate))
TIMES = DATEADD(HOUR,CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id])),@startdate),
1 AS VALUE
FROM sys.all_objects AS s1
CROSS JOIN
sys.all_objects AS s2
)
select DATEADD(HOUR,((DATEDIFF(HOUR, @startdate,TIMES)/@interval)*@interval),@startdate) AS TIMES,SUM(VALUE) AS TESTDATA
from ALL_INTERVALS
group by DATEADD(HOUR,((DATEDIFF(HOUR, @startdate,TIMES)/@interval)*@interval),@startdate)
order by DATEADD(HOUR,((DATEDIFF(HOUR, @startdate,TIMES)/@interval)*@interval),@startdate)
分钟
请注意。 你可以将你的间隔设置为60来实现小时,将1440设置为达到数天......
declare @startdate datetime2
declare @enddate datetime2
declare @interval int
set @startdate = '2017-01-01 00:00:00'
set @enddate = '2017-01-31 00:00:00'
set @interval = 7
;with
ALL_INTERVALS
AS (
SELECT TOP (DATEDIFF(MINUTE,@startdate,@enddate))
TIMES = DATEADD(MINUTE,CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id])),@startdate),
1 AS VALUE
FROM sys.all_objects AS s1
CROSS JOIN
sys.all_objects AS s2
)
select DATEADD(MINUTE,((DATEDIFF(MINUTE, @startdate,TIMES)/@interval)*@interval),@startdate) AS TIMES,SUM(VALUE) AS TESTDATA
from ALL_INTERVALS
group by DATEADD(MINUTE,((DATEDIFF(MINUTE, @startdate,TIMES)/@interval)*@interval),@startdate)
order by DATEADD(MINUTE,((DATEDIFF(MINUTE, @startdate,TIMES)/@interval)*@interval),@startdate)
答案 0 :(得分:2)
我认为你已经过度复杂化了
您可以每隔30分钟使用GROUP BY (DATEDIFF(MINUTE, '2017-01-01', TheDateTime) / 30
进行分组。当然,我选择的日期只是一个随机日期。如果需要,您可以选择样本数据中的第一个(或最后一个)日期
您还可以使用此技术获取任何时间段的每个时间间隔 - 只需将关键字MINUTE
更改为您要使用的任何日期部分,并将intreval 30
更改为您想要的任何时间间隔。
考虑以下示例数据:
;WITH CTE AS
(
SELECT CAST('2017-01-01T00:00:00' as datetime) As TheDateTime, 0 as rn
UNION ALL
SELECT DATEADD(MINUTE, 1, TheDateTime), rn + 1
FROM CTE
WHERE rn < 60
)
SELECT TheDateTime, rn INTO #T
FROM CTE
OPTION(MAXRECURSION 0)
#T
现在包含以下数据:
TheDateTime rn
2017-01-01 00:00:00.000 0
2017-01-01 00:01:00.000 1
2017-01-01 00:02:00.000 2
2017-01-01 00:03:00.000 3
...
2017-01-01 00:59:00.000 59
2017-01-01 01:00:00.000 60
要将最大rn分组30分钟,您只需要:
SELECT DATEDIFF(MINUTE, '2017-01-01', TheDateTime) / 30, MAX(rn)
FROM #T
GROUP BY DATEDIFF(MINUTE, '2017-01-01', TheDateTime) / 30
结果:
interval max_rn
0 29
1 59
2 60