2012-10-18 125 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 - 檢查我的編輯,我的意思是先前添加一個例子... –