SQL Server
is not particularly good in rolling/cumulative queries.
You can use this:
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
, however, this may not be very efficient, since it will count the same overlapping intervals over an over again.
For the larger invervals, it may be even better to use a CURSOR
-based solution that would allow to keep intermediate results (though normally they are worse performance-wise than pure set-based solutions).
Oracle
and PostgreSQL
support this clause:
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
which keeps an internal window buffer and is very efficient.
SQL Server
, unfortunately, does not support moving windows.