Töne wie eine Anwendung für Fensterfunktionen . Aber leider ist das nicht der Fall. Fensterrahmen können nur auf Zeilenzahlen basieren, nicht auf tatsächlichen Spaltenwerten.
Eine einfache Abfrage mit LEFT JOIN
kann die Arbeit erledigen:
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
Funktioniert nicht mit time
wie in Ihrer Minimal-Demo, da das nicht rund läuft. Ich nehme an, es ist vernünftig, timestamp
anzunehmen oder timestamptz
.
Da Sie jede Zeile selbst in die Zählung einbeziehen, ist ein INNER JOIN
würde auch funktionieren. (LEFT JOIN
ist angesichts möglicher NULL-Werte noch zuverlässiger.)
Oder verwenden Sie einen LATERAL
Unterabfrage und Sie müssen nicht auf der äußeren Abfrageebene aggregieren:
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;
Verwandte:
Für große Tabellen und viele Zeilen im Zeitrahmen eine prozedurale Lösung, die einmal durch die Tabelle geht wird besser abschneiden. Wie:
- Fensterfunktionen oder allgemeine Tabellenausdrücke:Vorherige Zeilen innerhalb des Bereichs zählen
- Alternativen zu defektem PL/Ruby:Konvertieren einer Warehouse-Journaltabelle
- GROUP BY und aggregieren fortlaufende numerische Werte