Ljud som en applikation för fönsterfunktioner . Men tyvärr är det inte så. Fönsterramar kan bara baseras på radantal, inte på faktiska kolumnvärden.
En enkel fråga med LEFT JOIN
kan göra jobbet:
SELECT t0.order_id
, count(t1.time_created) AS count_within_3_sec
FROM tbl t0
LEFT JOIN tbl t1 ON t1.time_created BETWEEN t0.time_created - interval '3 sec'
AND t0.time_created
GROUP BY 1
ORDER BY 1;
db<>fiol här
Fungerar inte med time
som i din minimala demo, eftersom det inte går runt. Jag antar att det är rimligt att anta timestamp
eller timestamptz
.
Eftersom du inkluderar varje rad själv i räkningen, en INNER JOIN
skulle funka också. (LEFT JOIN
är fortfarande mer tillförlitlig inför möjliga NULL-värden.)
Eller använd en LATERAL
subquery och du behöver inte aggregera på den yttre frågenivån:
SELECT t0.order_id
, t1.count_within_3_sec
FROM tbl t0
LEFT JOIN LATERAL (
SELECT count(*) AS count_within_3_sec
FROM tbl t1
WHERE t1.time_created BETWEEN t0.time_created - interval '3 sec'
AND t0.time_created
) t1 ON true
ORDER BY 1;
Relaterat:
För stora tabeller och många rader i tidsramen, en procedurlösning som går igenom tabellen en gång kommer att prestera bättre. Gilla:
- Fönsterfunktioner eller vanliga tabelluttryck:räkna tidigare rader inom intervallet
- Alternativ till trasig PL/ruby:konvertera en lagerjournaltabell
- GROUP BY and aggregate sekventiella numeriska värden