Нарастающий итог SUM + ORDER BY

Оконные функции начинают вести себя интересно, если внутрь OVER добавить ORDER BY.

Посмотри внимательно на столбцы count_current и count_total в результате запроса:

SELECT pi.purchase_id,
       pi.purchase_item_id,
       pi.count AS count_item,
       sum(pi.count) over (ORDER BY pi.purchase_id, pi.purchase_item_id) AS count_current,
       sum(pi.count) over () AS count_total
  FROM purchase_item pi
 ORDER BY pi.purchase_id,
          pi.purchase_item_id
# purchase_id purchase_item_id count_item count_current count_total
1 1 1 1 1 54
2 1 2 30 31 54
3 2 3 1 32 54
4 3 4 1 33 54
5 3 5 1 34 54
6 4 6 2 36 54
7 5 7 1 37 54
8 6 8 1 38 54
9 6 9 1 39 54
10 6 10 1 40 54
11 7 11 3 43 54
12 8 12 1 44 54
13 9 13 1 45 54
14 10 14 5 50 54
15 10 15 1 51 54
16 10 16 1 52 54
17 11 17 1 53 54
18 11 18 1 54 54

С sum(pi.count) over () AS count_total все понятно. Так как в over ничего не указано, то sum вычисляется по всем строкам.

Но если внутри over написать ORDER BY, то функция будет вычисляться не по всем строкам, а от первой строки и до текущей, включительно (не совсем так конечно, но об этом в следующих заданиях).

Чтобы вычислить агрегатную функцию по окну с указанием ORDER BY внутри over, делай так:

  1. Разбивай все строки результата на группы в соответствии с PARTITION BY, указанным в over. В нашем случае PARTITION BY опущен, поэтому группа у нас одна - все строки.
  2. Сортируй строки в группах в порядке, указанном в ORDER BY внутри over.
  3. Вычисляй функцию последовательно для строк, начиная с первой. Для каждой очередной строки для вычисления значения бери строки от начала и до текущей.

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

Для первой строки берем одну единственную строку

# purchase_id purchase_item_id count_item count_current count_total
1 1 1 1 1 54

Для второй:

# purchase_id purchase_item_id count_item count_current count_total
1 1 1 1 1 54
2 1 2 30 31 54
31 = 1 + 30

Для третьей:

# purchase_id purchase_item_id count_item count_current count_total
1 1 1 1 1 54
2 1 2 30 31 54
3 2 3 1 32 54
32 = 1 + 30 + 1

И так далее...

С ORDER BY себя так ведут все агрегатные оконные функции, не только sum.

11.7 Обработка NULL значений

11.9 Неуникальные значения в нарастающем итоге SUM + ORDER BY