Window Functions (part2) - cumulative aggregates
Continuing with the window functions support for Firebird 3, I have now added another OVER
sub-clause: ORDER BY. The ORDER BY sub-clause can be used with or without partitions, and it makes aggregate functions return the
partial aggregations as the records are being processed.
Considering our employee table has this data:
| id | salary |
|---|---|
| 1 | 10.00 |
| 2 | 12.00 |
| 3 | 8.00 |
| 4 | 9.00 |
| 5 | 10.00 |
And we run this query:
select
id, salary, sum(salary) over (order by salary) cum_salary
from employee
order by salary;
The result set produced will be:
| id | salary | cum_salary |
|---|---|---|
| 3 | 8.00 | 8.00 |
| 4 | 9.00 | 17.00 |
| 1 | 10.00 | 37.00 |
| 5 | 10.00 | 37.00 |
| 2 | 12.00 | 49.00 |
So cum_salary returns the partial/accumulated aggregation (of the SUM function). You may found strange the 37.00 repeated for the ids
1 and 5, but that is how it should work. The ORDER BY keys are grouped together and the aggregation is computed once (but summing the
two 10.00).
You can use multiple windows with different orders, and ORDER BY parts like DESC, NULLS LAST, etc. Here is a weird example:
select
id, salary,
sum(salary) over (order by salary) cum_salary,
sum(salary) over (order by salary desc) cum_salary_desc
from employee
order by salary;
The result set produced will be:
| id | salary | cum_salary | cum_salary_desc |
|---|---|---|---|
| 3 | 8.00 | 8.00 | 49.00 |
| 4 | 9.00 | 17.00 | 41.00 |
| 1 | 10.00 | 37.00 | 32.00 |
| 5 | 10.00 | 37.00 | 32.00 |
| 2 | 12.00 | 49.00 | 12.00 |
With a partition ORDER BY works the same way, but at each partition boundary the aggregation is reset.
All aggregation functions are usable with ORDER BY, except the LIST function. As LIST returns blob, it would be slow to return
multiple blobs (one for each order group), trick to implement, and I don't see an usage scenario for it.