Dźwięki jak aplikacja dla funkcji okien . Ale niestety tak nie jest. Ramki okien mogą być oparte tylko na liczbie wierszy, a nie na rzeczywistych wartościach kolumn.
Proste zapytanie z LEFT JOIN
może wykonać pracę:
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 tutaj
Nie działa z time
jak w twoim minimalnym demo, ponieważ to się nie kończy. Przypuszczam, że rozsądne jest założenie timestamp
lub timestamptz
.
Ponieważ uwzględniasz każdy wiersz w liczniku, INNER JOIN
też zadziała. (LEFT JOIN
jest jeszcze bardziej niezawodny w obliczu możliwych wartości NULL).
Lub użyj LATERAL
podzapytanie i nie trzeba agregować na zewnętrznym poziomie zapytania:
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;
Powiązane:
W przypadku dużych tabel i wielu wierszy w ramach czasowych rozwiązanie proceduralne, które przechodzi przez tabelę raz będzie działać lepiej. Na przykład:
- Funkcje okien lub wspólne wyrażenia tabelowe:licz poprzednie wiersze w zakresie
- Alternatywy dla uszkodzonego PL/ruby:przekonwertuj tabelę dziennika magazynowego
- GROUP BY i agregacja sekwencyjne wartości liczbowe