Lyde som et program til vinduefunktioner . Men det er desværre ikke tilfældet. Vinduesrammer kan kun baseres på rækkeantal, ikke på faktiske kolonneværdier.
En simpel forespørgsel med LEFT JOIN
kan klare opgaven:
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<>fiddle her
Virker ikke med time
som i din minimale demo, da det ikke går rundt. Jeg formoder, at det er rimeligt at antage timestamp
eller timestamptz
.
Da du inkluderer hver række selv i optællingen, er en INNER JOIN
ville også virke. (LEFT JOIN
er stadig mere pålidelig i forhold til mulige NULL-værdier.)
Eller brug en LATERAL
underforespørgsel, og du behøver ikke aggregere på det ydre forespørgselsniveau:
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;
Relateret:
For store borde og mange rækker i tidsrammen, en proceduremæssig løsning, der går gennem tabellen én gang vil præstere bedre. Ligesom:
- Vinduefunktioner eller almindelige tabeludtryk:tæl tidligere rækker inden for rækkevidde
- Alternativer til ødelagt PL/ruby:Konverter en lagerjournaltabel
- GROUP BY and aggregate sekventielle numeriske værdier