Оконные функции начинают вести себя интересно, если внутрь 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, делай так:
- Разбивай все строки результата на группы в соответствии с
PARTITION BY, указанным вover. В нашем случаеPARTITION BYопущен, поэтому группа у нас одна - все строки. - Сортируй строки в группах в порядке, указанном в
ORDER BYвнутриover. - Вычисляй функцию последовательно для строк, начиная с первой. Для каждой очередной строки для вычисления значения бери строки от начала и до текущей.
Для наглядности у результате у нас строки отсортированы в том же порядке, что и при вычислении оконной функции.
Для первой строки берем одну единственную строку
| # | 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.