1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5
>Window Functions</TITLE
8
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
10
HREF="mailto:pgsql-docs@postgresql.org"><LINK
12
TITLE="PostgreSQL 9.1beta1 Documentation"
13
HREF="index.html"><LINK
15
TITLE="Advanced Features"
16
HREF="tutorial-advanced.html"><LINK
19
HREF="tutorial-transactions.html"><LINK
22
HREF="tutorial-inheritance.html"><LINK
25
HREF="stylesheet.css"><META
26
HTTP-EQUIV="Content-Type"
27
CONTENT="text/html; charset=ISO-8859-1"><META
29
CONTENT="2011-04-27T21:20:33"></HEAD
35
SUMMARY="Header navigation table"
47
>PostgreSQL 9.1beta1 Documentation</A
57
HREF="tutorial-transactions.html"
66
TITLE="Advanced Features"
67
HREF="tutorial-advanced.html"
74
>Chapter 3. Advanced Features</TD
80
TITLE="Advanced Features"
81
HREF="tutorial-advanced.html"
90
HREF="tutorial-inheritance.html"
104
NAME="TUTORIAL-WINDOW"
105
>3.5. Window Functions</A
111
> performs a calculation across a set of
112
table rows that are somehow related to the current row. This is comparable
113
to the type of calculation that can be done with an aggregate function.
114
But unlike regular aggregate functions, use of a window function does not
115
cause rows to become grouped into a single output row — the
116
rows retain their separate identities. Behind the scenes, the window
117
function is able to access more than just the current row of the query
121
> Here is an example that shows how to compare each employee's salary
122
with the average salary in his or her department:
125
CLASS="PROGRAMLISTING"
126
>SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;</PRE
131
> depname | empno | salary | avg
132
-----------+-------+--------+-----------------------
133
develop | 11 | 5200 | 5020.0000000000000000
134
develop | 7 | 4200 | 5020.0000000000000000
135
develop | 9 | 4500 | 5020.0000000000000000
136
develop | 8 | 6000 | 5020.0000000000000000
137
develop | 10 | 5200 | 5020.0000000000000000
138
personnel | 5 | 3500 | 3700.0000000000000000
139
personnel | 2 | 3900 | 3700.0000000000000000
140
sales | 3 | 4800 | 4866.6666666666666667
141
sales | 1 | 5000 | 4866.6666666666666667
142
sales | 4 | 4800 | 4866.6666666666666667
146
The first three output columns come directly from the table
150
>, and there is one output row for each row in the
151
table. The fourth column represents an average taken across all the table
152
rows that have the same <TT
155
> value as the current row.
156
(This actually is the same function as the regular <CODE
160
aggregate function, but the <TT
163
> clause causes it to be
164
treated as a window function and computed across an appropriate set of
168
> A window function call always contains an <TT
172
directly following the window function's name and argument(s). This is what
173
syntactically distinguishes it from a regular function or aggregate
177
> clause determines exactly how the
178
rows of the query are split up for processing by the window function.
186
dividing the rows into groups, or partitions, that share the same
190
> expression(s). For each row,
191
the window function is computed across the rows that fall into the
192
same partition as the current row.
195
> You can also control the order in which rows are processed by
196
window functions using <TT
206
> does not even have to match the
207
order in which the rows are output.) Here is an example:
210
CLASS="PROGRAMLISTING"
211
>SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;</PRE
216
> depname | empno | salary | rank
217
-----------+-------+--------+------
218
develop | 8 | 6000 | 1
219
develop | 10 | 5200 | 2
220
develop | 11 | 5200 | 2
221
develop | 9 | 4500 | 4
222
develop | 7 | 4200 | 5
223
personnel | 2 | 3900 | 1
224
personnel | 5 | 3500 | 2
231
As shown here, the <CODE
234
> function produces a numerical rank
235
within the current row's partition for each distinct <TT
239
value, in the order defined by the <TT
246
> needs no explicit parameter, because its behavior
247
is entirely determined by the <TT
253
> The rows considered by a window function are those of the <SPAN
257
> produced by the query's <TT
260
> clause as filtered by its
271
if any. For example, a row removed because it does not meet the
275
> condition is not seen by any window function.
276
A query can contain multiple window functions that slice up the data
277
in different ways by means of different <TT
281
they all act on the same collection of rows defined by this virtual table.
284
> We already saw that <TT
287
> can be omitted if the ordering
288
of rows is not important. It is also possible to omit <TT
292
>, in which case there is just one partition containing all the rows.
295
> There is another important concept associated with window functions:
296
for each row, there is a set of rows within its partition called its
300
>. Many (but not all) window functions act only
301
on the rows of the window frame, rather than of the whole partition.
305
> is supplied then the frame consists of
306
all rows from the start of the partition up through the current row, plus
307
any following rows that are equal to the current row according to the
315
default frame consists of all rows in the partition.
324
Here is an example using <CODE
330
CLASS="PROGRAMLISTING"
331
>SELECT salary, sum(salary) OVER () FROM empsalary;</PRE
348
> Above, since there is no <TT
355
clause, the window frame is the same as the partition, which for lack of
359
> is the whole table; in other words each sum is
360
taken over the whole table and so we get the same result for each output
361
row. But if we add an <TT
364
> clause, we get very different
368
CLASS="PROGRAMLISTING"
369
>SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;</PRE
386
> Here the sum is taken from the first (lowest) salary up through the
387
current one, including any duplicates of the current one (notice the
388
results for the duplicated salaries).
391
> Window functions are permitted only in the <TT
398
> clause of the query. They are forbidden
399
elsewhere, such as in <TT
409
> clauses. This is because they logically
410
execute after the processing of those clauses. Also, window functions
411
execute after regular aggregate functions. This means it is valid to
412
include an aggregate function call in the arguments of a window function,
416
> If there is a need to filter or group rows after the window calculations
417
are performed, you can use a sub-select. For example:
420
CLASS="PROGRAMLISTING"
421
>SELECT depname, empno, salary, enroll_date
423
(SELECT depname, empno, salary, enroll_date,
424
rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos
427
WHERE pos < 3;</PRE
430
The above query only shows the rows from the inner query having
437
> When a query involves multiple window functions, it is possible to write
438
out each one with a separate <TT
441
> clause, but this is
442
duplicative and error-prone if the same windowing behavior is wanted
443
for several functions. Instead, each windowing behavior can be named
447
> clause and then referenced in <TT
454
CLASS="PROGRAMLISTING"
455
>SELECT sum(salary) OVER w, avg(salary) OVER w
457
WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);</PRE
461
> More details about window functions can be found in
463
HREF="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS"
467
HREF="functions-window.html"
471
HREF="queries-table-expressions.html#QUERIES-WINDOW"
475
HREF="sql-select.html"
494
HREF="tutorial-window.html#AEN1050"
505
> There are options to define the window frame in other ways, but
506
this tutorial does not cover them. See
508
HREF="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS"
520
SUMMARY="Footer navigation table"
531
HREF="tutorial-transactions.html"
549
HREF="tutorial-inheritance.html"
565
HREF="tutorial-advanced.html"
b'\\ No newline at end of file'