在SQL Server中创建时间间隔

时间:2012-12-03 11:57:21

标签: sql sql-server sql-server-2008 datetime

我在SQL Server中有一个表,用于存储事件和事件的datetime。我现在希望将这些事件分组到例如 10分钟间隔显示每组中有多少事件。

我正在寻找类似于以下的结果。有没有人有一个例子og如何做到这一点?

    FromTIme                | ToTime                  | Number of Events
    -----------------------------------------------------------------------
    2012-12-03 00:00:00.000 | 2012-12-03 00:10:00.000 |     5
    2012-12-03 00:10:00.000 | 2012-12-03 00:20:00.000 |    15

该查询将用于报告中,因此我希望能够设置间隔的@StartDate@EndDate

1 个答案:

答案 0 :(得分:5)

你可以这样做:

DECLARE @startDate DATETIME = '2012-12-03 00:00:00.000';
DECLARE @endDate   DATETIME = '2012-12-03 00:20:00.000';
DECLARE @counter INT = 1;
DECLARE @nOfIntervals INT = DATEDIFF(minute, @startDate, @endDate) / 10;

;WITH Temp
AS
(
    SELECT n
    FROM (VALUES(0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) Nums(n)
), Numbers
AS
(
    SELECT n = t2.n * 10 + t1.n + 0
    FROM Temp t1
    CROSS JOIN Temp t2
), FromToCTE
AS
(
    SELECT  
      DATEADD(minute, 10 * n, @startDate) FromDate, 
      DATEADD(minute, 10 *(n +1), @startDate) ToDate
    FROM numbers 
    WHERE (n + 1) <= @nOfIntervals
 ),EventsFromTo
 AS
 (
     SELECT 
       c.FromDate,
       c.ToDate,
       e.EventDate
     FROM @Events e
     INNER JOIN FromToCTE c ON e.EventDate BETWEEN c.FromDate AND c.ToDate
 )  
 SELECT FromDate, ToDate, COUNT(*) "Number of Events"
 FROM EventsFromTo
 GROUP BY FromDate, ToDate;

Live Demo

这会给你类似的东西:

     FromDate                 ToDate          Number of Events
2012-12-03 00:00:00     2012-12-03 00:10:00          5
2012-12-03 00:10:00     2012-12-03 00:20:00          15 

这是如何工作的?

我使用了一个临时表,其中0到9之间的数字作为锚表:

SELECT n
FROM (VALUES(0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) Nums(n)

要生成0到99之间的数字:

Numbers
AS
(
    SELECT n = t2.n * 10 + t1.n + 0
    FROM Temp t1
    CROSS JOIN Temp t2
 )

我使用此表Numbers生成从@startDate@endDate的时间间隔,我假设两个日期之间的差异不会超过99分钟。如果要使查询适用于大于99的更多范围,只需将表格临时交叉连接更多次以生成更多数字。后来我使用这些生成的数字来生成日期时间间隔,每个间隔时间间隔为10分钟。之后,我在事件日期字段中使用Events表加入了这个生成的表。我们已经完成了GROUP BYCOUNT

请注意:我没有检查使用两个参数@startDate@EndDate传递给查询的日期差异是否可以在10分钟内完成,我是认为你可能需要在你的情况下检查一下,我会留下它作为你的作业。

这可能是很多工作,但我没有找到一种简单的方法来做到这一点而不使用游标