Я пытаюсь получить некоторые усредненные интервальные значения некоторых разреженных необработанных данных для заданной начальной и конечной даты/времени плюс размер интервала в секундах. Это мой первый удар:полные интервалы с вмененными значениями
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
Спасибо. Я не уверен, что вы имеете в виду: «если у вас есть предельное значение, например, 00:30:00, его следует рассматривать только один раз». Это еще не достигнуто: a.StartRange <метка времени и a.EndRange> = отметка времени? – cs0815
Вы правы :) –
Я еще не тестировал ваш подход, но мой довольно медленный, как только я пытаюсь сделать это в течение месяца или более. Считаете ли вы, что ваш подход быстрее? – cs0815