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_valueist 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

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top