2012-10-18 124 views
1

我想写一个TSQL过程来计算给定日期范围之间的高峰时间,并按照给定的时间分割。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米范围

我应该使用间隔?我怎么解决这个问题?任何帮助?

回答

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 
+0

这正是我想要的。谢谢 – cihata87

+0

但这里有一个问题。当我的结束时间是11:00时,程序不会在11:00停止,最后一行是在11点和11点05分之间?我们如何解决这个问题? – cihata87

+0

@ cihata87 - 对不起。我已经纠正了递归终止检查。 – HABO

0

对DATEADD函数使用循环。

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

不断增加你的“分钟” inteval直到产生日期比年底大。

编辑

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递归查询解决方案更直接/易于理解,尽管公认不太优雅。

+0

你可以更具体一点吗?如何在这个问题上使用datepart? – cihata87

+0

@ cihata87 - 检查我的编辑,我的意思是先前添加一个例子... –