Очистить накопленную сумму вместе с сгруппированной суммой - PullRequest
0 голосов
/ 23 сентября 2018

Я работаю в PostgreSQL 9.6.6

Ради воспроизводимости я буду использовать create tempory table, чтобы создать "постоянную" таблицу для игры:

create temporary table test_table as 
    select * from 
            (values 
                ('2018-01-01', 2),
                ('2018-01-01', 3),
                ('2018-02-01',  1),
                ('2018-02-01', 2))
            as t (month, count)

Aselect * from test_table возвращает следующее:

   month    | count 
------------+-------
 2018-01-01 |     2
 2018-01-01 |     3
 2018-02-01 |     1
 2018-02-01 |     2

Требуется следующий результат:

   month    | sum | cumulative_sum 
------------+-----+----------------
 2018-01-01 |   5 |              5
 2018-02-01 |   3 |              8

Другими словами, значения суммируются, группируются по месяцам, а затем кумулятивносумма отображается в другом столбце.

Проблема в том, что единственный способ, которым я знаю, добиться этого, является несколько запутанным.Сначала должна быть вычислена сгруппированная сумма (как с подвыбором или оператором with), а затем подсчет выполнения вычисляется с оператором выбора для этой таблицы, как показано ниже:

with sums as 
    (select month,
        sum(count) as sum
    from test_table
    group by 1)
select month,
    sum,
    sum(sum) over (order by month) as cumulative_sum
from sums

Что я желаю, чтобы мог бы работать, было бы что-то вроде ...

select month,
    sum(count) as sum,
    sum(count) over (order by month) as cumulative_sum
from test_table
group by 1

Но это возвращает

ERROR:  column "test_table.count" must appear in the GROUP BY clause or be used in an aggregate function
LINE 3:    sum(count) over (order by month) as cumulative_sum

Кажется, что суета с предложением group by не суетитсяудовлетворять PSQL.

TL, DR : есть ли способ в PSQL для вычисления как суммы по группам, так и кумулятивной суммы по группам, используя только один оператор select?В более общем смысле, есть ли «предпочтительный» способ сделать это, помимо метода, который я использую в этом вопросе?

1 Ответ

0 голосов
/ 23 сентября 2018

Ваша догадка использовать SUM в качестве аналитической функции была на правильном пути, но вам необходимо аналитическую сумму совокупной суммы:

SELECT month,
    SUM(count) as sum,
    SUM(SUM(count)) OVER (ORDER BY month) AS cumulative_sum
FROM test_table
GROUP BY 1;

enter image description here

Демонстрация

Что касается того, почему это работает, аналитические функции применяются после выполнения условия GROUP BY.Таким образом, общая сумма фактически доступна, когда мы берем скользящую сумму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...