【问题标题】:time range and date range in TSQLSQL中的时间范围和日期范围
【发布时间】:2012-10-18 19:50:10
【问题描述】:

我想在 TSQL 中编写一个程序,计算给定日期范围之间的峰值时间,这些时间范围划分为给定时间。

Start time: 10-02-2012 10:00
End time  : 10-02 2012 11:00
time range: every 5 minutes

原来如此:

10:00 range 1  -> 5 peak times
10:05 range 2  -> 11 peak times
.
.
.
11:00 range 11 -> 7 peak times

当时间范围为 30 分钟时,代码将计算 2 个范围

我应该使用间隔吗?我怎么解决这个问题?有什么帮助吗?

【问题讨论】:

    标签: sql-server sql-server-2008 tsql date-range


    【解决方案1】:

    您可以这样确定时间范围:

    declare @StartTime as DateTime = '10-02-2012 10:00'
    declare @EndTime as DateTime ='10-02-2012 11:00'
    declare @TimeRange as Time = '00:05:00.000'
    
    ; with TimeRanges as (
      select @StartTime as StartTime, @StartTime + @TimeRange as EndTime
      union all
      select StartTime + @TimeRange, EndTime + @TimeRange
        from TimeRanges
        where EndTime < @EndTime ) -- Corrected.
      select StartTime, EndTime
        from TimeRanges
    

    将范围与您的样本数据相结合以获得摘要:

    declare @StartTime as DateTime = '10-02-2012 10:00'
    declare @EndTime as DateTime ='10-02-2012 11:00'
    declare @TimeRange as Time = '00:05:00.000'
    
    declare @Samples as Table ( SampleId Int Identity, SampleTime DateTime )
    insert into @Samples ( SampleTime ) values
      ( '10-02-2012 9:00' ), ( '10-02-2012 10:00' ), ( '10-02-2012 10:02' ), ( '10-02-2012 10:02' ),
      ( '10-02-2012 10:05' ), ( '10-02-2012 10:20' ), ( '10-02-2012 10:34' ), ( '10-02-2012 11:30' )
    
    ; with TimeRanges as (
      select @StartTime as StartTime, @StartTime + @TimeRange as EndTime
      union all
      select StartTime + @TimeRange, EndTime + @TimeRange
        from TimeRanges
        where EndTime < @EndTime ) -- Corrected.
      select StartTime, EndTime, Count( S.SampleId ) as Samples
        from TimeRanges as TR left outer join
          @Samples as S on TR.StartTime <= S.SampleTime and S.SampleTime < TR.EndTime
        group by TR.StartTime, TR.EndTime
    

    【讨论】:

    • 但是这里有一个问题。当我结束时间是 11:00 时,程序不会在 11:00 停止最后一行是在 11:00 和 11:05 之间吗?我们该如何解决这个问题?
    • @cihata87 - 很抱歉。我已经更正了递归终止检查。
    • HABO 我想要每日报告时遇到问题 24:00:00.000 不起作用并引发错误,23:59:59 导致我的报告出现延迟,我们该如何解决?有什么建议吗?
    • @cihata87 - 我对你的最后评论有点不清楚。每日报告将从一个日期运行到下一个日期,例如@StartTime = '10-10-2012 00:00'@EndDate = '10-11-2012 00:00。如果您说您想以一种奇怪的方式显示日期/时间,那么您可以随时自行格式化,例如case when EndTime = @EndTime and Cast( @EndTime as Time ) = '00:00' then Convert( VarChar(10), DateAdd( day, -1, EndTime ), 121 ) + ' 23:59:60.000' else Convert( VarChar(23), EndTime, 121 ) end as FunnyTime.
    【解决方案2】:

    使用带有 DATEADD 函数的循环。

    http://msdn.microsoft.com/en-us/library/ms186819.aspx

    继续添加“分钟”间隔,直到结果日期大于结束日期。

    编辑

    BEGIN
    -- setup
    DECLARE @start DATETIME
    DECLARE @end DATETIME
    DECLARE @interval INT
    DECLARE @samples TABLE (
        [time] DATETIME
    )
    SET @start = CAST('10-02-2012 10:00' as DATETIME)
    SET @end = CAST('10-02-2012 11:00' as DATETIME)
    SET @interval = 5
    INSERT INTO @samples VALUES 
        ( '10-02-2012 9:00' ), ( '10-02-2012 10:00' ), ( '10-02-2012 10:02' )
        , ( '10-02-2012 10:02' ), ( '10-02-2012 10:05' ), ( '10-02-2012 10:20' )
        , ( '10-02-2012 10:34' ), ( '10-02-2012 11:30' )
    -- make the ranges
    DECLARE @ranges TABLE (
        [start] datetime
        ,[end] datetime
    )
    DECLARE @tmp DATETIME
    SET @tmp = DATEADD(minute, @interval, @start)
    IF @tmp > @end BEGIN SET @tmp = @end END
    WHILE @start < @end
        BEGIN
        INSERT INTO @ranges VALUES (@start, @tmp)
        SET @start = @tmp
        SET @tmp = DATEADD(minute, @interval, @start)
        IF @tmp > @end BEGIN SET @tmp = @end END
        END
    -- execute the query
    SELECT r.[start], r.[end], count(s.[time]) [count]
    FROM @ranges r
        LEFT JOIN @samples s 
            ON r.[start] <= s.[time] AND r.[end] > s.[time]
    GROUP BY r.[start], r.[end]
    END
    

    我建议使用简单的 while 循环来生成您想要的范围。对我来说,它比 CTE 递归查询解决方案更直接/更容易理解,尽管公认不那么优雅。

    【讨论】:

    • 你能说得更具体点吗?如何在这个问题上使用 datepart?
    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 2017-12-20
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多