Geluiden zoals een toepassing voor vensterfuncties . Maar helaas is dat niet het geval. Raamkozijnen kunnen alleen worden gebaseerd op het aantal rijen, niet op werkelijke kolomwaarden.
Een eenvoudige zoekopdracht met LEFT JOIN
kan het werk doen:
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 hier
Werkt niet met time
zoals in je minimale demo, want dat is niet rond. Ik veronderstel dat het redelijk is om aan te nemen timestamp
of timestamptz
.
Aangezien u elke rij zelf in de telling opneemt, wordt een INNER JOIN
zou ook werken. (LEFT JOIN
is nog betrouwbaarder in het licht van mogelijke NULL-waarden.)
Of gebruik een LATERAL
subquery en u hoeft niet te aggregeren op het buitenste queryniveau:
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;
Gerelateerd:
Voor grote tafels en veel rijen in het tijdsbestek, een procedurele oplossing die eenmaal door de tafel loopt beter zal presteren. Vind ik leuk:
- Vensterfuncties of algemene tabeluitdrukkingen:tel vorige rijen binnen bereik
- Alternatieven voor gebroken PL/ruby:converteer een magazijnjournaaltabel
- GROUP BY en aggregaat opeenvolgende numerieke waarden