PostgreSQL-сумма не распознается как агрегатная функция?

Мне нужно иметь текущее количество транзакций в год. Таким образом, если общая сумма в 2015 была 150, а в 2016 общая сумма была 90. Это означает, что при 2016 текущий объем составляет 240. И так далее.

Итак, у меня есть эти данные:

CREATE table transactions2(year_num int, amount int);

insert into transactions2 values(2015, 100);
insert into transactions2 values(2015, 50);
insert into transactions2 values(2016, 90);
insert into transactions2 values(2017, 100);
insert into transactions2 values(2019, 200);

SELECT year_num, count(amount), sum(amount) 
OVER (ORDER BY year_num) 
FROM transactions2 
GROUP BY year_num ORDER BY year_num;

Если я запускаю этот выбор SQL, я получаю:

ERROR:  column "transactions2.amount" must appear in the GROUP BY clause or be used in an aggregate function
LINE 9: SELECT year_num, count(amount), sum(amount) OVER (ORDER BY y...
                                            ^

********** Error **********

ERROR: column "transactions2.amount" must appear in the GROUP BY clause or be used in an aggregate function
SQL state: 42803
Character: 328

Но у меня есть amount в функции sum. Итак, почему это не работает? Если я оберну это как sum(count(sum)), то это сработает, но мне не нужна сумма количества, мне просто нужна сумма.

Нужно ли мне писать внутренний выбор только для этого?


person Andrius    schedule 28.03.2017    source источник
comment
почему OVER (ЗАКАЗАТЬ ПО year_num)?   -  person Jack    schedule 28.03.2017
comment
@ Джек, потому что мне нужна общая сумма, как объяснено в вопросе. Он должен добавить итог предыдущего года к следующему году и так далее. С OVER это можно сделать.   -  person Andrius    schedule 28.03.2017
comment
Хорошо - я никогда не использовал OVER для подобных вещей; Я бы написал это с внутренним запросом   -  person Jack    schedule 28.03.2017
comment
sum(sum(amount)) over ... тоже должно работать, но ответ @klin проще (и уже объясняет, почему).   -  person pozs    schedule 28.03.2017


Ответы (1)


В выражении:

sum(amount) OVER (ORDER BY year_num) 

sum() - это не просто агрегат, это оконная функция.

Вероятно, вы захотите использовать как count(), так и sum() в качестве оконных функций:

SELECT DISTINCT year_num, count(amount) over w, sum(amount) over w
FROM transactions2 
WINDOW w as (ORDER BY year_num)
ORDER BY year_num;

 year_num | count | sum 
----------+-------+-----
     2015 |     2 | 150
     2016 |     3 | 240
     2017 |     4 | 340
     2019 |     5 | 540
(4 rows)
person klin    schedule 28.03.2017
comment
Потому что я забыл DISTINCT, извините. Ответ отредактирован. - person klin; 28.03.2017