我想在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个范围
我应该使用Interval吗?我怎么解决这个问题?任何帮助?
答案 0 :(得分: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
答案 1 :(得分:0)
使用带有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递归查询解决方案更直接/易于理解,尽管不太优雅。