PostgreSQL-Fensterfunktion mit LIMIT
-
22-12-2019 - |
Frage
Die folgende Abfrage gruppiert die Ergebnisse von first
in 4 gleichmäßig verteilte Datumsbereiche und aggregiert einen Durchschnitt für the_value
in jedem Behälter.
WITH first as(
SELECT
extract(EPOCH FROM foo.t_date) as the_date,
foo_val as the_value
FROM bar
INNER JOIN foo
ON
foo.user_id = bar.x_id
and
foo.user_name = 'xxxx'
)
SELECT bin, round(sum(bin_sum) OVER w /sum(bin_ct) OVER w, 2) AS running_avg
FROM (
SELECT width_bucket(first.the_date
, x.min_epoch, x.max_epoch, x.bins) AS bin
, sum(first.the_value) AS bin_sum
, count(*) AS bin_ct
FROM first
, (SELECT MIN(first.the_date) AS min_epoch
, MAX(first.the_date) AS max_epoch
, 4 AS bins
FROM first
) x
GROUP BY 1
) sub
WINDOW w AS (ORDER BY bin)
ORDER BY 1;
Ich würde gerne nur den Durchschnitt für den niedrigsten Wert, sagen wir 20, berechnen können the_value
ist in jeder Tonne.Aus anderen Beiträgen hier auf Stackoverflow habe ich gesehen, dass dies möglich ist und dass dies vielleicht der Fall ist ORDER BY the_value
Und rank()
ist der beste Weg, dies zu tun.Mein Problem besteht jedoch darin, dass ich nicht sicher bin, wo meine aktuelle Abfrage geändert werden soll, um dies zu implementieren.
Jeder Einblick wäre dankbar.
Postgres-Version 9.3
Lösung
Verwenden row_number()
auf jedem Behälter.
Berechnen Sie zunächst die Zeilennummer rn
, dann bewerben WHERE rn < 21
im nächsten Schritt:
WITH first AS (
SELECT extract(EPOCH FROM foo.t_date) AS the_date
, foo_val AS the_value
FROM bar
JOIN foo ON foo.user_id = bar.x_id
AND foo.user_name = 'xxxx'
)
, x AS (
SELECT MIN(the_date) AS min_epoch
, MAX(the_date) AS max_epoch
FROM first
)
, y AS (
SELECT width_bucket(f.the_date, x.min_epoch, x.max_epoch, 4) AS bin, *
FROM first f, x
)
, z AS (
SELECT row_number() OVER (PARTITION BY bin ORDER BY the_value) AS rn, *
FROM y
)
SELECT bin, round(sum(bin_sum) OVER w / sum(bin_ct) OVER w, 2) AS running_avg
FROM (
SELECT bin
, sum(the_value) AS bin_sum
, count(*) AS bin_ct
FROM z
WHERE rn < 21 -- max 20 lowest values
GROUP BY 1
) sub
WINDOW w AS (ORDER BY bin)
ORDER BY 1;
CTEs y
Und z
könnte verwechselt werden.Ähnlich first
Und x
könnte verwechselt werden.
Aber so ist es klarer.
Ungetestet, da uns keine Testdaten vorliegen.