SQL查询计算给定时间范围内的记录数,填补空白

时间:2012-09-03 22:35:15

标签: tsql

我正在尝试计算在给定时间段(通常为15分钟)之间的记录数,但我希望将此时间间隔设为变量。我的表有一个日期时间列,我需要计算两个日期之间每15分钟间隔的记录数量,当15分钟窗口没有任何记录时,我需要该时间段为零。我尝试过以不同的组合使用CTE,但无法使用它。我可以使用CTE生成日期系列,但无法获得结果中的实际数据。我有一个使用带有WHILE循环的存储过程的工作解决方案。如果可能的话,我希望避免这种情况或更优雅的解决方案。

这是我使用临时表的工作循环:

declare @record_count int = 0
declare @end_date_per_query datetime
create table #output (
    SessionIdTime datetime,
    CallCount int)
while @date_from < @date_to
begin   
    set @end_date_per_query = DATEADD(minute, @interval, @date_from)
    select @record_count = COUNT(*) from tbl WHERE SessionIdTime between @date_from and @end_date_per_query
    insert into #output values (@date_from, @record_count)
    set @date_from = @end_date_per_query
end
select * from #output order by sessionIdTime
drop table #output

希望有人可以提供更优雅的解决方案。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

CTE工作正常:

-- Parameters.
declare @Start as DateTime = '20120901'
declare @End as DateTime = '20120902'
declare @Interval as Time = '01:00:00.00' -- One hour.  Change to 15 minutes.
select @Start as [Start], @End as [End], @Interval as [Interval]

-- Sample data.
declare @Sessions as Table ( SessionId Int Identity, SessionStart DateTime )
insert into @Sessions ( SessionStart ) values
  ( '20120831 12:15:07' ), ( '20120831 21:51:18' ),
  ( '20120901 12:15:07' ), ( '20120901 21:51:18' ),  
  ( '20120902 12:15:07' ), ( '20120902 21:51:18' )  
select * from @Sessions

-- Summary.    
; with SampleWindows as (
  select @Start as WindowStart, @Start + @Interval as WindowEnd
  union all
  select SW.WindowStart + @Interval, SW.WindowEnd + @Interval
    from SampleWindows as SW
    where SW.WindowEnd < @End
  )
  select SW.WindowStart, Count( S.SessionStart ) as [Sessions]
    from SampleWindows as SW left outer join
      @Sessions as S on SW.WindowStart <= S.SessionStart and S.SessionStart < SW.WindowEnd
    group by SW.WindowStart

答案 1 :(得分:0)

这是你要找的吗?

-- setup
DECLARE @interval INT, @start DATETIME
SELECT @interval = 15, @start = '1/1/2000 0:00:00'
DECLARE @t TABLE (id INT NOT NULL IDENTITY(1,1) PRIMARY KEY, d DATETIME)
INSERT INTO @t (d) VALUES
 (DATEADD(mi, @interval * 0.00, @start)) -- in
,(DATEADD(mi, @interval * 0.75, @start)) -- in
,(DATEADD(mi, @interval * 1.50, @start)) -- out

-- query
DECLARE @result INT
SELECT @result = COUNT(*) FROM @t
WHERE d BETWEEN @start AND DATEADD(mi, @interval, @start)

-- result
PRINT @result