В предыдущей серии: "Но если внутри over написать ORDER BY, то функция будет вычисляться не по всем строкам, а от первой строки и до текущей, включительно (не совсем так конечно, но об этом в следующих заданиях)."
Разберем, что значит "не совсем так". Посмотри на запрос и его результат:
SELECT pi.purchase_id,
pi.count,
sum(pi.count) over (ORDER BY pi.purchase_id, pi.count) AS count_current,
sum(pi.count) over () AS count_total
FROM purchase_item pi
ORDER BY pi.purchase_id,
pi.count
| # | purchase_id | count | count_current | count_total |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 54 |
| 2 | 1 | 30 | 31 | 54 |
| 3 | 2 | 1 | 32 | 54 |
| 4 | 3 | 1 | 34 | 54 |
| 5 | 3 | 1 | 34 | 54 |
| 6 | 4 | 2 | 36 | 54 |
| 7 | 5 | 1 | 37 | 54 |
| 8 | 6 | 1 | 40 | 54 |
| 9 | 6 | 1 | 40 | 54 |
| 10 | 6 | 1 | 40 | 54 |
| 11 | 7 | 3 | 43 | 54 |
| 12 | 8 | 1 | 44 | 54 |
| 13 | 9 | 1 | 45 | 54 |
| 14 | 10 | 1 | 47 | 54 |
| 15 | 10 | 1 | 47 | 54 |
| 16 | 10 | 5 | 52 | 54 |
| 17 | 11 | 1 | 54 | 54 |
| 18 | 11 | 1 | 54 | 54 |
Особо интересуют строки
| # | purchase_id | count | count_current | count_total |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
| 3 | 2 | 1 | 32 | 54 |
| 4 | 3 | 1 | 34 | 54 |
| 5 | 3 | 1 | 34 | 54 |
| 6 | 4 | 2 | 36 | 54 |
| ... | ... | ... | ... | ... |
На 3-ей строке count_current был равен 32. На 4-й count равен 1, и казалось бы count_current должен быть равен 33 (32 + 1). Но он равен 34.
Причины становятся ясны, если взглянуть на ORDER BY в оконной функции и на 5-ю строку.
(ORDER BY pi.purchase_id, pi.count)
| # | purchase_id | count | count_current | count_total |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
| 3 | 2 | 1 | . | . |
| 4 | 3 | 1 | . | . |
| 5 | 3 | 1 | . | . |
| 6 | 4 | 2 | . | . |
| ... | ... | ... | ... | ... |
В 4-й и 5-й строке оба значения purchase_id и count совпадают. Поэтому с точки зрения сортировки они не различаются.
Агрегатные оконные функции для вычисления значения для очередной строки включают в набор все строки с совпадающими значениями из ORDER BY. Именно по этому в 4-й и 5-й строках count_current равен 34 (32 + 1 + 1).
Для вычисления значения count_current в 4-й и 5-й строке брались строки
| # | purchase_id | count | count_current | count_total |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 54 |
| 2 | 1 | 30 | 31 | 54 |
| 3 | 2 | 1 | 32 | 54 |
| 4 | 3 | 1 | 34 | 54 |
| 5 | 3 | 1 | 34 | 54 |
Для строк с 8 по 10 агрегатная функция так же принимает одинаковое значение:
| # | purchase_id | count | count_current | count_total |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
| 7 | 5 | 1 | 37 | 54 |
| 8 | 6 | 1 | 40 | 54 |
| 9 | 6 | 1 | 40 | 54 |
| 10 | 6 | 1 | 40 | 54 |
| 11 | 7 | 3 | 43 | 54 |
| ... | ... | ... | ... | ... |
40 = 37 + 1 + 1 + 1
P.S. В оконных функциях можно явно задавать размер окна (группу строк) для вычисления значения. Возможностей задания окна достаточно много и они заслуживают отдельной темы.