我正在尝试为每个定义的开始和结束日期/时间加上间隔大小(以秒为单位)获取一些稀疏原始数据的平均间隔值。这是我的第一个刺:
declare
@StartTime datetime = '2013-11-01 00:00:00.000',
@EndTime datetime = '2013-11-02 00:00:00.000',
@IntervalInSeconds int = 1800
drop table #Events
create table #Events
(
Timestamp datetime,
DisplayValue real
)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:00:01.000', 2)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:00:01.000', 3)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:30:01.000', 4)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:30:01.000', 5)
;WITH CompleteSequence AS
(
SELECT
@StartTime AS StartRange,
DATEADD(second, @IntervalInSeconds, @StartTime) AS EndRange
UNION ALL
SELECT
EndRange,
DATEADD(second, @IntervalInSeconds, EndRange)
FROM CompleteSequence
WHERE DATEADD(second, @IntervalInSeconds, EndRange) <= @EndTime
)
SELECT
StartRange,
AVG(NULLIF(DisplayValue,0))
FROM CompleteSequence as a
left outer join #Events as b on a.StartRange < Timestamp and a.EndRange >= Timestamp
where Timestamp >= @StartTime and Timestamp <= @EndTime
group by StartRange
不幸的是,结果:
2013-11-01 00:00:00.000 2.5
2013-11-01 00:30:00.000 4.5
实际上应该是 48 个值,理想情况下,“缺失数据”应该用整个时间段的平均值进行估算(在这种情况下是 (2 + 3 + 4 + 5) / 4 = 3.5。我使用 NULLIF 等来估算至少 0 没有成功。有什么想法吗?
PS:
这是另一种尝试,似乎有效。欢迎任何改进建议:
declare
@StartTime datetime = '2013-11-01 00:00:00.000',
@EndTime datetime = '2013-11-02 00:00:00.000',
@IntervalInSeconds int = 1800,
@Average real = 0
drop table #Events
create table #Events
(
Timestamp datetime,
DisplayValue real
)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:00:01.000', 2)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:00:01.000', 3)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:30:01.000', 4)
insert into #Events (Timestamp, DisplayValue) values ('2013-11-01 00:30:01.000', 5)
select @Average = AVG(DisplayValue) from #Events
;WITH CompleteSequence AS
(
SELECT
@StartTime AS StartRange,
DATEADD(second, @IntervalInSeconds, @StartTime) AS EndRange
UNION ALL
SELECT
EndRange,
DATEADD(second, @IntervalInSeconds, EndRange)
FROM CompleteSequence
WHERE DATEADD(second, @IntervalInSeconds, EndRange) <= @EndTime
)
SELECT
StartRange,
ISNULL(AVG(DisplayValue), @Average)
FROM CompleteSequence as a
left outer join #Events as b on (a.StartRange < Timestamp and a.EndRange >= Timestamp)
where (Timestamp >= @StartTime and Timestamp <= @EndTime) or Timestamp is null
group by StartRange