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

Как да заявите сумата на предишния ред на същата колона с pgSql

Използвайте дефиниран от потребителя агрегат

Тест на живо:http://sqlfiddle.com/#!17/03ee7/1

DDL

CREATE TABLE t (grop varchar(1), month_year text, something int);INSERT INTO t (grop, month_year, something)VALUES ('a', '201901', -2), ('a ', '201902', -4), ('a', '201903', -6), ('a', '201904', 60), ('a', '201905', -2), (' a', '201906', 9), ('a', '201907', ​​11), ('b', '201901', 100), ('b', '201902', -200), ('b ', '201903', 300), ('b', '201904', -50), ('b', '201905', 30), ('b', '201906', -88), ('b ', '201907', ​​-86); 

Дефиниран от потребителя агрегат

създайте или заменете функция negative_accum(_accumulated_b numeric, _current_b numeric)връща число като$$ изберете случай, когато _accumulated_b <0 тогава _accumulated_b + _current_b else _current_b end$$ език 'sql';създайте сборен negative_summer(numeric)( sfunc =negative_accum, stype =numeric, initcond =0); изберете *, negative_summer(нещо) над (подреждане по група, месец_година) като резултат от t 

Първият параметър (_accumulated_b) съдържа натрупаната стойност на колоната. Вторият параметър (_current_b) съдържа стойността на колоната на текущия ред.

Изход:

Що се отнася до вашия псевдокод B3 =A3 + MIN(0, B2)

Използвах този типичен код:

изберете случай, когато _accumulated_b <0 след това _accumulated_b + _current_belse _current_bend 

Това може да се напише идиоматично в Postgres като:

изберете _current_b + least(_accumulated_b, 0) 

Тест на живо:http://sqlfiddle.com/#!17/70fa8/1

създаване или замяна на функция negative_accum(_accumulated_b numeric, _current_b numeric)връща число като$$ select _current_b + least(_accumulated_b, 0) $$ език 'sql'; 

Можете също да използвате друг език с акумулираща функция, например plpgsql. Обърнете внимание, че plpgsql (или може би цитатът $$) не се поддържа в http://sqlfiddle.com . Така че няма тестова връзка на живо, но това ще работи на вашата машина:

създайте или заменете функция negative_accum(_accumulated_b numeric, _current_b numeric)връща число as$$begin return _current_b + least(_accumulated_b, 0);end$$ език 'plpgsql'; 

АКТУАЛИЗАЦИЯ

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

Тест на живо:http://sqlfiddle.com/#!17/87795/4

INSERT INTO t (grop, month_year, something)VALUES ('a', '201901', -2), ('a', '201902', -4), ('a', '201903 ', -6), ('a', '201904', 60), ('a', '201905', -2), ('a', '201906', 9), ('a', '201907 ', -11), -- промени това от 11 на -11 ('b', '201901', 100), ('b', '201902', -200), ('b', '201903', 300 ), ('b', '201904', -50), ('b', '201905', 30), ('b', '201906', -88), ('b', '201907', ​​- 86); 

Изход:

<предварителен код>| хващам | месец_година | нещо | резултат_грешен | резултат ||------|------------|-----------|--------------| --------|| a | 201901 | -2 | -2 | -2 || a | 201902 | -4 | -6 | -6 || a | 201903 | -6 | -12 | -12 || a | 201904 | 60 | 48 | 48 || a | 201905 | -2 | -2 | -2 || a | 201906 | 9 | 7 | 7 || a | 201907 | -11 | -11 | -11 || б | 201901 | 100 | 89 | 100 || б | 201902 | -200 | -200 | -200 || б | 201903 | 300 | 100 | 100 || б | 201904 | -50 | -50 | -50 || б | 201905 | 30 | -20 | -20 || б | 201906 | -88 | -108 | -108 || б | 201907 | -86 | -194 | -194 |

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgresSql:Сравняване на две таблици и получаване на техния резултат и сравнение с третата таблица

  2. PostgreSQL за намиране на средна точка между две времеви марки

  3. 3 начина за изброяване на всички функции в PostgreSQL

  4. недефиниран индекс за бисквитка в някои браузъри

  5. Postgres не може да отвори CSV файл за достъп за четене:разрешението е отказано