Chapter 10. Window (Analytical) Functions
According to the SQL specification, window functions (also known as analytical functions) are a kind of aggregation, but one that does not filter the result set of a query. The rows of aggregated data are mixed with the query result set.
The window functions are used with the OVER
clause. They may appear only in the SELECT
list, or the ORDER BY
clause of a query.
Firebird window functions may be partitioned and ordered.
Syntax
<window_function> ::=
<aggregate_function> OVER <window_name_or_spec>
| <window_function_name> ([<expr> [, <expr> ...]])
OVER <window_name_or_spec>
<aggregate_function> ::=
!! See Aggregate Functions !!
<window_name_or_spec> ::=
<window_specification> | existing_window_name
<window_function_name> ::=
<ranking_function>
| <navigational_function>
<ranking_function> ::=
RANK | DENSE_RANK | PERCENT_RANK | ROW_NUMBER
| CUME_DIST | NTILE
<navigational_function>
LEAD | LAG | FIRST_VALUE | LAST_VALUE | NTH_VALUE
<window_specification> ::=
( [existing_window_name] [<window_partition>]
[<window_order>] [<window_frame>] )
<window_partition> ::=
[PARTITION BY <expr> [, <expr> ...]]
<window_order> ::=
[ORDER BY
<expr> [<direction>] [<nulls_placement>]
[, <expr> [<direction>] [<nulls_placement>] ...]
<direction> ::= {ASC | DESC}
<nulls_placement> ::= NULLS {FIRST | LAST}
<window_frame> ::= {RANGE | ROWS} <window_frame_extent>
<window_frame_extent> ::=
<window_frame_start> | <window_frame_between>
<window_frame_start> ::=
UNBOUNDED PRECEDING | <expr> PRECEDING | CURRENT ROW
<window_frame_between> ::=
BETWEEN <window_frame_bound_1> AND <window_frame_bound_2>
<window_frame_bound_1> ::=
UNBOUNDED PRECEDING | <expr> PRECEDING | CURRENT ROW
| <expr> FOLLOWING
<window_frame_bound_2> ::=
<expr> PRECEDING | CURRENT ROW | <expr> FOLLOWING
| UNBOUNDED FOLLOWING
Table 10.1 Window Function Arguments
Argument | Description |
---|---|
expr | Expression. May contain a table column, constant, variable, expression, scalar or aggregate function. Window functions are not allowed as an expression. |
aggregate_function | An aggregate function used as a window function |
existing_window_name | A named window defined using the WINDOW clause of the current query specification. |
10.1 Aggregate Functions as Window Functions
All aggregate functions — including FILTER
clause — can be used as window functions, by adding the OVER
clause.
Imagine a table EMPLOYEE
with columns ID
, NAME
and SALARY
, and the need to show each employee with their respective salary and the percentage of their salary over the payroll.
A normal query could achieve this, as follows:
select
id,
department,
salary,
salary / (select sum(salary) from employee) portion
from employee
order by id;
Results
id department salary portion
-- ---------- ------ ----------
1 R & D 10.00 0.2040
2 SALES 12.00 0.2448
3 SALES 8.00 0.1632
4 R & D 9.00 0.1836
5 R & D 10.00 0.2040
The query is repetitive and lengthy to run, especially if EMPLOYEE
happens to be a complex view.
The same query could be specified in a much faster and more elegant way using a window function:
select
id,
department,
salary,
salary / sum(salary) OVER () portion
from employee
order by id;
Here, sum(salary) over ()
is computed with the sum of all SALARY
from the query (the EMPLOYEE
table).