4 CREATE TEMPORARY TABLE empsalary (
10 INSERT INTO empsalary VALUES
11 ('develop', 10, 5200, '2007-08-01'),
12 ('sales', 1, 5000, '2006-10-01'),
13 ('personnel', 5, 3500, '2007-12-10'),
14 ('sales', 4, 4800, '2007-08-08'),
15 ('personnel', 2, 3900, '2006-12-23'),
16 ('develop', 7, 4200, '2008-01-01'),
17 ('develop', 9, 4500, '2008-01-01'),
18 ('sales', 3, 4800, '2007-08-01'),
19 ('develop', 8, 6000, '2006-10-01'),
20 ('develop', 11, 5200, '2007-08-15');
21 SELECT depname, empno, salary, sum(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname, salary;
22 depname | empno | salary | sum
23 -----------+-------+--------+-------
24 develop | 7 | 4200 | 25100
25 develop | 9 | 4500 | 25100
26 develop | 11 | 5200 | 25100
27 develop | 10 | 5200 | 25100
28 develop | 8 | 6000 | 25100
29 personnel | 5 | 3500 | 7400
30 personnel | 2 | 3900 | 7400
31 sales | 3 | 4800 | 14600
32 sales | 4 | 4800 | 14600
33 sales | 1 | 5000 | 14600
36 SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary) FROM empsalary;
37 depname | empno | salary | rank
38 -----------+-------+--------+------
39 develop | 7 | 4200 | 1
40 develop | 9 | 4500 | 2
41 develop | 11 | 5200 | 3
42 develop | 10 | 5200 | 3
43 develop | 8 | 6000 | 5
44 personnel | 5 | 3500 | 1
45 personnel | 2 | 3900 | 2
52 SELECT four, ten, SUM(SUM(four)) OVER (PARTITION BY four), AVG(ten) FROM tenk1
53 GROUP BY four, ten ORDER BY four, ten;
54 four | ten | sum | avg
55 ------+-----+------+------------------------
56 0 | 0 | 0 | 0.00000000000000000000
57 0 | 2 | 0 | 2.0000000000000000
58 0 | 4 | 0 | 4.0000000000000000
59 0 | 6 | 0 | 6.0000000000000000
60 0 | 8 | 0 | 8.0000000000000000
61 1 | 1 | 2500 | 1.00000000000000000000
62 1 | 3 | 2500 | 3.0000000000000000
63 1 | 5 | 2500 | 5.0000000000000000
64 1 | 7 | 2500 | 7.0000000000000000
65 1 | 9 | 2500 | 9.0000000000000000
66 2 | 0 | 5000 | 0.00000000000000000000
67 2 | 2 | 5000 | 2.0000000000000000
68 2 | 4 | 5000 | 4.0000000000000000
69 2 | 6 | 5000 | 6.0000000000000000
70 2 | 8 | 5000 | 8.0000000000000000
71 3 | 1 | 7500 | 1.00000000000000000000
72 3 | 3 | 7500 | 3.0000000000000000
73 3 | 5 | 7500 | 5.0000000000000000
74 3 | 7 | 7500 | 7.0000000000000000
75 3 | 9 | 7500 | 9.0000000000000000
78 SELECT depname, empno, salary, sum(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname);
79 depname | empno | salary | sum
80 -----------+-------+--------+-------
81 develop | 11 | 5200 | 25100
82 develop | 7 | 4200 | 25100
83 develop | 9 | 4500 | 25100
84 develop | 8 | 6000 | 25100
85 develop | 10 | 5200 | 25100
86 personnel | 5 | 3500 | 7400
87 personnel | 2 | 3900 | 7400
88 sales | 3 | 4800 | 14600
89 sales | 1 | 5000 | 14600
90 sales | 4 | 4800 | 14600
93 SELECT depname, empno, salary, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary) ORDER BY rank() OVER w;
94 depname | empno | salary | rank
95 -----------+-------+--------+------
96 develop | 7 | 4200 | 1
97 personnel | 5 | 3500 | 1
100 personnel | 2 | 3900 | 2
101 develop | 9 | 4500 | 2
103 develop | 11 | 5200 | 3
104 develop | 10 | 5200 | 3
105 develop | 8 | 6000 | 5
108 -- empty window specification
109 SELECT COUNT(*) OVER () FROM tenk1 WHERE unique2 < 10;
124 SELECT COUNT(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS ();
139 -- no window operation
140 SELECT four FROM tenk1 WHERE FALSE WINDOW w AS (PARTITION BY ten);
145 -- cumulative aggregate
146 SELECT sum(four) OVER (PARTITION BY ten ORDER BY unique2) AS sum_1, ten, four FROM tenk1 WHERE unique2 < 10;
161 SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10;
176 SELECT rank() OVER (PARTITION BY four ORDER BY ten) AS rank_1, ten, four FROM tenk1 WHERE unique2 < 10;
178 --------+-----+------
191 SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
192 dense_rank | ten | four
193 ------------+-----+------
206 SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
207 percent_rank | ten | four
208 -------------------+-----+------
214 0.666666666666667 | 7 | 1
221 SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
222 cume_dist | ten | four
223 -------------------+-----+------
224 0.666666666666667 | 0 | 0
225 0.666666666666667 | 0 | 0
236 SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10;
251 SELECT ntile(NULL) OVER (ORDER BY ten, four), ten, four FROM tenk1 LIMIT 2;
258 SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
273 SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
288 SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
303 SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
318 SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
333 SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
348 SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
349 first_value | ten | four
350 -------------+-----+------
363 -- last_value returns the last row of the frame, which is CURRENT ROW in ORDER BY window.
364 SELECT last_value(four) OVER (ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
365 last_value | ten | four
366 ------------+-----+------
379 SELECT last_value(ten) OVER (PARTITION BY four), ten, four FROM
380 (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s
382 last_value | ten | four
383 ------------+-----+------
396 SELECT nth_value(ten, four + 1) OVER (PARTITION BY four), ten, four
397 FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s;
398 nth_value | ten | four
399 -----------+-----+------
412 SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER (PARTITION BY two ORDER BY ten) AS wsum
413 FROM tenk1 GROUP BY ten, two;
414 ten | two | gsum | wsum
415 -----+-----+-------+--------
416 0 | 0 | 45000 | 45000
417 2 | 0 | 47000 | 92000
418 4 | 0 | 49000 | 141000
419 6 | 0 | 51000 | 192000
420 8 | 0 | 53000 | 245000
421 1 | 1 | 46000 | 46000
422 3 | 1 | 48000 | 94000
423 5 | 1 | 50000 | 144000
424 7 | 1 | 52000 | 196000
425 9 | 1 | 54000 | 250000
428 SELECT count(*) OVER (PARTITION BY four), four FROM (SELECT * FROM tenk1 WHERE two = 1)s WHERE unique2 < 10;
439 SELECT (count(*) OVER (PARTITION BY four ORDER BY ten) +
440 sum(hundred) OVER (PARTITION BY four ORDER BY ten))::varchar AS cntsum
441 FROM tenk1 WHERE unique2 < 10;
456 -- opexpr with different windows evaluation.
458 SELECT count(*) OVER (PARTITION BY four ORDER BY ten) +
459 sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total,
460 count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount,
461 sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum
464 WHERE total <> fourcount + twosum;
465 total | fourcount | twosum
466 -------+-----------+--------
469 SELECT avg(four) OVER (PARTITION BY four ORDER BY thousand / 100) FROM tenk1 WHERE unique2 < 10;
471 ------------------------
472 0.00000000000000000000
473 0.00000000000000000000
474 0.00000000000000000000
475 1.00000000000000000000
476 1.00000000000000000000
477 1.00000000000000000000
478 1.00000000000000000000
484 SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER win AS wsum
485 FROM tenk1 GROUP BY ten, two WINDOW win AS (PARTITION BY two ORDER BY ten);
486 ten | two | gsum | wsum
487 -----+-----+-------+--------
488 0 | 0 | 45000 | 45000
489 2 | 0 | 47000 | 92000
490 4 | 0 | 49000 | 141000
491 6 | 0 | 51000 | 192000
492 8 | 0 | 53000 | 245000
493 1 | 1 | 46000 | 46000
494 3 | 1 | 48000 | 94000
495 5 | 1 | 50000 | 144000
496 7 | 1 | 52000 | 196000
497 9 | 1 | 54000 | 250000
500 -- more than one window with GROUP BY
502 row_number() OVER (ORDER BY depname),
503 sum(sum(salary)) OVER (ORDER BY depname DESC)
504 FROM empsalary GROUP BY depname;
505 sum | row_number | sum
506 -------+------------+-------
512 -- identical windows with different names
513 SELECT sum(salary) OVER w1, count(*) OVER w2
514 FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary);
530 SELECT lead(ten, (SELECT two FROM tenk1 WHERE s.unique2 = unique2)) OVER (PARTITION BY four ORDER BY ten)
531 FROM tenk1 s WHERE unique2 < 10;
547 SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE FALSE)s;
552 -- mixture of agg/wfunc in the same window
553 SELECT sum(salary) OVER w, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
569 SELECT empno, depname, salary, bonus, depadj, MIN(bonus) OVER (ORDER BY empno), MAX(depadj) OVER () FROM(
571 CASE WHEN enroll_date < '2008-01-01' THEN 2008 - extract(YEAR FROM enroll_date) END * 500 AS bonus,
573 AVG(salary) OVER (PARTITION BY depname) < salary
574 THEN 200 END AS depadj FROM empsalary
576 empno | depname | salary | bonus | depadj | min | max
577 -------+-----------+--------+-------+--------+------+-----
578 1 | sales | 5000 | 1000 | 200 | 1000 | 200
579 2 | personnel | 3900 | 1000 | 200 | 1000 | 200
580 3 | sales | 4800 | 500 | | 500 | 200
581 4 | sales | 4800 | 500 | | 500 | 200
582 5 | personnel | 3500 | 500 | | 500 | 200
583 7 | develop | 4200 | | | 500 | 200
584 8 | develop | 6000 | 1000 | 200 | 500 | 200
585 9 | develop | 4500 | | | 500 | 200
586 10 | develop | 5200 | 500 | 200 | 500 | 200
587 11 | develop | 5200 | 500 | 200 | 500 | 200
590 -- test non-default frame specifications
592 sum(ten) over (partition by four order by ten),
593 last_value(ten) over (partition by four order by ten)
594 FROM (select distinct ten, four from tenk1) ss;
595 four | ten | sum | last_value
596 ------+-----+-----+------------
620 sum(ten) over (partition by four order by ten range between unbounded preceding and current row),
621 last_value(ten) over (partition by four order by ten range between unbounded preceding and current row)
622 FROM (select distinct ten, four from tenk1) ss;
623 four | ten | sum | last_value
624 ------+-----+-----+------------
648 sum(ten) over (partition by four order by ten range between unbounded preceding and unbounded following),
649 last_value(ten) over (partition by four order by ten range between unbounded preceding and unbounded following)
650 FROM (select distinct ten, four from tenk1) ss;
651 four | ten | sum | last_value
652 ------+-----+-----+------------
675 SELECT four, ten/4 as two,
676 sum(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row),
677 last_value(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row)
678 FROM (select distinct ten, four from tenk1) ss;
679 four | two | sum | last_value
680 ------+-----+-----+------------
703 SELECT four, ten/4 as two,
704 sum(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row),
705 last_value(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row)
706 FROM (select distinct ten, four from tenk1) ss;
707 four | two | sum | last_value
708 ------+-----+-----+------------
732 SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0;
737 -- ordering by a non-integer constant is allowed
738 SELECT rank() OVER (ORDER BY length('abc'));
744 -- but this draws an error: "ORDER BY 1" means order by first SELECT column
745 SELECT rank() OVER (ORDER BY 1);
746 ERROR: window functions not allowed in window definition
747 LINE 1: SELECT rank() OVER (ORDER BY 1);
750 SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY salary) < 10;
751 ERROR: window functions not allowed in WHERE clause
752 LINE 1: SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY sa...
754 SELECT * FROM empsalary INNER JOIN tenk1 ON row_number() OVER (ORDER BY salary) < 10;
755 ERROR: window functions not allowed in JOIN conditions
756 LINE 1: SELECT * FROM empsalary INNER JOIN tenk1 ON row_number() OVE...
758 SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GROUP BY 1;
759 ERROR: window functions not allowed in GROUP BY clause
760 LINE 1: SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GRO...
762 SELECT * FROM rank() OVER (ORDER BY random());
763 ERROR: cannot use window function in function expression in FROM
764 LINE 1: SELECT * FROM rank() OVER (ORDER BY random());
766 DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())) > 10;
767 ERROR: window functions not allowed in WHERE clause
768 LINE 1: DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())...
770 DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random());
771 ERROR: cannot use window function in RETURNING
772 LINE 1: DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random...
774 SELECT count(*) OVER w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY unique1);
775 ERROR: window "w" is already defined
776 LINE 1: ...w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY ...
778 SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM tenk1;
779 ERROR: syntax error at or near "ORDER"
780 LINE 1: SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM te...
782 SELECT count() OVER () FROM tenk1;
783 ERROR: count(*) must be used to call a parameterless aggregate function
784 LINE 1: SELECT count() OVER () FROM tenk1;
786 SELECT generate_series(1, 100) OVER () FROM empsalary;
787 ERROR: OVER specified, but generate_series is not a window function nor an aggregate function
788 LINE 1: SELECT generate_series(1, 100) OVER () FROM empsalary;
790 SELECT ntile(0) OVER (ORDER BY ten), ten, four FROM tenk1;
791 ERROR: argument of ntile must be greater than zero
792 SELECT nth_value(four, 0) OVER (ORDER BY ten), ten, four FROM tenk1;
793 ERROR: argument of nth_value must be greater than zero
795 DROP TABLE empsalary;