SQL Server
не особенно хорош в скользящих / кумулятивных запросах.
Вы можете использовать это:
WITH q (unix_ts, cnt) AS
(
SELECT DATEDIFF(s, '1970-01-01', ts), COUNT(*)
FROM record
GROUP BY
DATEDIFF(s, '1970-01-01', ts)
)
SELECT *
FROM q q1
CROSS APPLY
(
SELECT AVG(cnt) AS smooth_cnt
FROM q q2
WHERE q2.unix_ts BETWEEN q1.unix_ts - 5 AND q1.unix_ts + 5
) q2
, однако, это может быть не очень эффективно, так как будет учитыватьсяодни и те же интервалы перекрытия снова и снова.
Для больших инверсий может быть даже лучше использовать решение на основе CURSOR
, которое позволит сохранить промежуточные результаты (хотя обычно они хуже по производительностичем решения, основанные только на множествах).
Oracle
и PostgreSQL
поддерживают этот пункт:
WITH q (unix_ts, cnt) AS
(
SELECT TRUNC(ts, 'ss'), COUNT(*)
FROM record
GROUP BY
TRUNC(ts, 'ss')
)
SELECT q.*,
AVG(cnt) OVER (ORDER BY unix_ts RANGE BETWEEN INTERVAL '-5' SECOND AND INTERVAL '5' SECOND)
FROM q
, который сохраняет внутренний буфер окна и очень эффективен.
SQL Server
, к сожалению, не поддерживает перемещение окон.