sql >> Databáze >  >> RDS >> PostgreSQL

Vlastní agregační funkce v PostgreSQL

Existuje mnoho způsobů, jak toho dosáhnout pomocí stávajících funkcí. Můžete použít stávající funkce okna first_value() a last_value() v kombinaci s DISTINCT nebo DISTINCT ON získat jej bez spojení a poddotazů:

SELECT DISTINCT ON (userid)
       userid
     , last_value(rank) OVER w  
     - first_value(rank) OVER w AS rank_delta
FROM   rankings
WINDOW w AS (PARTITION BY userid ORDER BY ts
             ROWS BETWEEN UNBOUNDED PRECEDING
             AND  UNBOUNDED FOLLOWING);

Všimněte si vlastních rámců pro funkce okna !

Nebo můžete použít základní agregační funkce v dílčím dotazu a JOIN:

SELECT userid, r2.rank - r1.rank AS rank_delta
FROM  (
  SELECT userid
       , min(ts) AS first_ts
       , max(ts) AS last_ts
   FROM  rankings
   GROUP BY 1
   ) sub
JOIN   rankings r1 USING (userid)
JOIN   rankings r2 USING (userid)
WHERE  r1.ts = first_ts
AND    r2.ts = last_ts;

Za předpokladu jedinečného (userid, rank) nebo by vaše požadavky byly nejednoznačné.

Ukázka SQL Fiddle.

Shichinin no samuraj


Na žádost v komentářích, totéž pouze pro posledních sedm řádků na ID uživatele (nebo tolik, kolik jich lze najít, pokud jich je méně):

Opět jeden z mnoha možných způsobů. Ale věřím, že tohle je jeden z nejkratších:

SELECT DISTINCT ON (userid)
       userid
     , first_value(rank) OVER w  
     - last_value(rank)  OVER w AS rank_delta
FROM   rankings
WINDOW w AS (PARTITION BY userid ORDER BY ts DESC
             ROWS BETWEEN CURRENT ROW AND 7 FOLLOWING)
ORDER  BY userid, ts DESC;

Všimněte si obráceného pořadí řazení. První řádek je „nejnovější“ záznam. Zahrnu rámec (max.) 7 řádků a vyberu pouze výsledky pro nejnovější záznam s DISTINCT ON .

Ukázka SQL Fiddle.



  1. otázka o proměnných vazby postgresql

  2. Spring Data Rest:Date is null dotaz vyvolá výjimku postgres

  3. Vezměte text ze souboru a vložte jej do tabulky mysql pomocí skriptu

  4. Důvody, proč v SQL Server 2005 nemají seskupený index