Оконные функции. Разница между range и rows.
Будем считать нарастающий итог salary работников в порядке даты найма. Подготовим для начала CTE для таблицы emp* таким образом.
select e.* from emp e cross join generate_series(1,3,1) num where deptno=10
Будем считать нарастающий итог 3 способами: по старинке - без явного указания окна, и с указанием в явном виде range between unbounded preceding and current row и rows between unbounded preceding and current row. Для учебных целей (наглядности) считать будем в разрезе ename.
with t as (
select e.*
from emp e
cross join generate_series(1,3,1) num
where deptno=10
)
select t.*
, sum (sal) over (partition by ename order by hiredate) run_total_default
, sum (sal) over (partition by ename
order by hiredate
range between unbounded preceding and current row) run_total_range
, sum (sal) over (partition by ename
order by hiredate
rows between unbounded preceding and current row) run_total_rows
from t
order by 2Итак, поведением по умолчанию - без указания в явном виде типа кадрирования - используется range. В этом случае мы считаем агрегат по всем строкам, имеющим одинаковые значения в выражении ORDER BY, что и текущая строка. В случае кадрирования rows between unbounded preceding and current row мы считаем сумму с самой 1 строки в окне по текущую.
IRL скорее всего на промышленных данных эти суммы будут совпадать. Но нюанс стоит знать.
Проверено на PostgreSQL 15.7, compiled by Visual C++ build 1938, 64-bit
*Скрипты создания таблицы и её наполнения можно взять здесь