# Databases : PostgreSQL : Advanced : Windows
TODO
```
Window Functions
A window function performs a calculation across a set of table rows
that are somehow related to the current row.
Unlike with aggregate functions, window functions do not cause rows to become
grouped into a single output row like non-window aggregate calls would.
Behind the scenes,
the window function is able to access more than just the current row of the query result.
SELECT depname, empno, salary, avg( salary ) OVER ( PARTITION BY depname )
FROM empsalary;
A window function call always contains an OVER clause
directly following the window function's name and argument(s).
The OVER clause determines exactly how the rows of the query
are split up for processing by the window function.
The PARTITION BY clause within OVER divides the rows into groups, or partitions,
that share the same values of the PARTITION BY expression(s).
You can also control the order in which rows are processed by window functions:
SELECT depname, empno, salary, rank() OVER ( PARTITION BY depname ORDER BY salary DESC )
FROM empsalary;
The rows considered by a window function are those of the “virtual table”
produced by the query's FROM clause
as filtered by its WHERE, GROUP BY, and HAVING clauses if any.
For example, a row removed because it does not meet the WHERE condition
is not seen by any window function.
A query can contain multiple window functions
that slice up the data in different ways using different OVER clauses,
but they all act on the same collection of rows defined by this virtual table.
It is also possible to omit PARTITION BY,
in which case there is a single partition containing all rows.
Window Frame
For each row, there is a set of rows within its partition called its window frame.
Some window functions act only on the rows of the window frame,
rather than of the whole partition.
By default, if ORDER BY is supplied then the frame consists of all rows
from the start of the partition up through the current row,
plus any following rows that are equal to the current row
according to the ORDER BY clause.
When ORDER BY is omitted the default frame consists of all rows in the partition.
SELECT salary, sum( salary ) OVER ( ORDER BY salary ) FROM empsalary;
salary | sum
--------+-------
3500 | 3500
3900 | 7400
4200 | 11600
... | ...
Window functions are permitted only in the SELECT list and the ORDER BY clause of the query.
If there is a need to filter or group rows after the window calculations are performed,
you can use a sub-select:
SELECT depname, empno, salary, enroll_date
FROM
( SELECT depname, empno, salary, enroll_date,
rank() OVER ( PARTITION BY depname ORDER BY salary DESC, empno ) AS pos
FROM empsalary
) AS ss
WHERE pos < 3;
When a query involves multiple window functions,
it is possible to write out each one with a separate OVER clause,
but this is duplicative and error-prone
if the same windowing behavior is wanted for several functions.
Instead, each windowing behavior can be named in a WINDOW clause and then referenced in OVER:
SELECT sum( salary ) OVER w, avg( salary ) OVER w
FROM empsalary
WINDOW w AS ( PARTITION BY depname ORDER BY salary DESC );
```