定義された開始日と終了日/時刻と秒単位の間隔サイズについて、いくつかのまばらな生データの平均間隔値を取得しようとしています。これは私の最初の刺し傷です:
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