PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Персонализирана агрегатна функция в PostgreSQL

Има много начини да постигнете това със съществуващите функции. Можете да използвате съществуващия прозоречни функции first_value() и last_value() , комбиниран с DISTINCT или DISTINCT ON за да го получите без обединения и подзаявки:

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);

Обърнете внимание на персонализираните рамки за функциите на прозореца !

Или можете да използвате основни агрегатни функции в подзаявка и 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;

Приема се уникален (userid, rank) , или вашите изисквания биха били двусмислени.

Демо на SQL Fiddle.

Шичинин не самурай


По искане в коментарите, същото само за последните седем реда на потребителско име (или колкото можете да намерите, ако са по-малко):

Отново един от многото възможни начини. Но смятам, че това е един от най-кратките:

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;

Обърнете внимание на обратния ред на сортиране. Първият ред е "най-новият" запис. Обхващам рамка от (макс.) 7 реда и избирам само резултатите за най-новия запис с DISTINCT ON .

Демо на SQL Fiddle.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Връща данни от подизбор, използван в INSERT в израз на обща таблица

  2. Не разбирам как работи nextval() на postgresql, може ли някой да обясни?

  3. Как Tan() работи в PostgreSQL

  4. Получаване на автоматично генериран ключ от вмъкване на ред през пролетта 3 / PostgreSQL 8.4.9

  5. PostgreSQL:Автоматизирано архивиране в Windows