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

Кумулативно добавяне с динамична база в Postgres

Създайте своя собствена агрегатна функция , която може да се използва като функция за прозорец.

Специализирана агрегатна функция

По-лесно е, отколкото си мислите:

CREATE OR REPLACE FUNCTION f_sum_cap50 (numeric, numeric)
  RETURNS numeric LANGUAGE sql AS
'SELECT CASE WHEN $1 > 50 THEN 0 ELSE $1 END + $2';

CREATE AGGREGATE sum_cap50 (numeric) (
  sfunc    = f_sum_cap50
, stype    = numeric
, initcond = 0
);

След това:

SELECT *, sum_cap50(val) OVER (PARTITION BY fk
                               ORDER BY created) > 50 AS threshold_met 
FROM   test
WHERE  fk = 5;

Резултат точно както е заявено.

db<>fiddle тук
Стар sqlfiddle

Обща агрегатна функция

За да работи за всякакви прагове и всеки (числов) тип данни , както и разрешаване на NULL ценностите :

CREATE OR REPLACE FUNCTION f_sum_cap (anyelement, anyelement, anyelement)
  RETURNS anyelement
  LANGUAGE sql STRICT AS
$$SELECT CASE WHEN $1 > $3 THEN '0' ELSE $1 END + $2;$$;

CREATE AGGREGATE sum_cap (anyelement, anyelement) (
  sfunc    = f_sum_cap
, stype    = anyelement
, initcond = '0'
);

След това, за да извикате с лимит от, да речем, 110 с произволен цифров тип:

SELECT *
     , sum_cap(val, '110') OVER (PARTITION BY fk
                                 ORDER BY created) AS capped_at_110
     , sum_cap(val, '110') OVER (PARTITION BY fk
                                 ORDER BY created) > 110 AS threshold_met 
FROM   test
WHERE  fk = 5;

db<>fiddle тук
Стар sqlfiddle

Обяснение

Във вашия случай не трябва да се защитаваме срещу NULL стойности от val е дефинирано NOT NULL . Ако NULL могат да бъдат включени, дефинирайте f_sum_cap() като STRICT и работи, защото (по документация ):

И функцията, и агрегатът приемат още един аргумент. За полиморфен вариант може да бъде твърдо кодиран тип данни или същият полиморфен тип като водещите аргументи.

Относно полиморфните функции:

Обърнете внимание на използването на нетипизирани низови литерали , а не числови литерали, които по подразбиране биха били integer !




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. psql:ФАТАЛНО:ролята на скитник не съществува

  2. Получаването на база данни е неправилно конфигурирано. Моля, посочете грешката в стойността на името

  3. PostgreSQL UPDATE замяна на подниз

  4. PostgreSQL EXPLAIN – Какви са разходите за заявка?

  5. грешка при свързване с база данни, свързана с кодирането