你如何按任何基于时间的间隔分组? [英] How do you group by any time based interval?

查看:37
本文介绍了你如何按任何基于时间的间隔分组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 SQL SERVER 中,您如何按任何基于时间的间隔进行分组?

In SQL SERVER How do you group by any time based interval?

为了节省一些时间,我想出了这个解决方案,对我来说效果很好.您可以生成任何时基,然后按任何间隔分组.非常适合做时间加权平均.如果有人有更好的方法来做这件事,我很乐意听取您的意见.

To save someone time I have come up with this solution, For me it works very well. You can generate any time base then group by any interval. Great for doing time weighted averages. If someone has a better way of doing this I would love to hear from you.

小时

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 以实现天......

Note. you can set your interval to 60 to achieve hours, 1440 to achieve days....

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)

推荐答案

我认为你把事情复杂化了.
您可以使用 GROUP BY (DATEDIFF(MINUTE, '2017-01-01', TheDateTime)/30 每 30 分钟分组一次.当然,我选择的日期只是一个随机日期.如果需要,您可以选择示例数据中的第一个(或最后一个)日期.
您还可以使用此技术获取任何时间部分的每个间隔 - 只需将关键字 MINUTE 更改为您要使用的任何日期部分,并将 intreval 30 更改为 any你想要的间隔.

I think you are over complicating thins.
You can use GROUP BY (DATEDIFF(MINUTE, '2017-01-01', TheDateTime) / 30 for grouping by every 30 minutes. Of course, the date I've chosen is a just a random date. You can choose, if you want, the first (or last) date in your sample data.
And you can also use this technique to get every interval of any time part - just change the keyword MINUTE to any date part you want to use, and the intreval 30 to any interval you want.

考虑以下示例数据:

;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

要获得按 30 分钟分组的最大 rn,您只需要:

To get the maximum rn grouped by 30 minutes you just need this:

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

这篇关于你如何按任何基于时间的间隔分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆