SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
depname | empno | salary | rank -----------+-------+--------+------ develop | 8 | 6000 | 1 develop | 10 | 5200 | 2 develop | 11 | 5200 | 2 develop | 9 | 4500 | 4 develop | 7 | 4200 | 5 personnel | 2 | 3900 | 1 personnel | 5 | 3500 | 2 sales | 1 | 5000 | 1 sales | 4 | 4800 | 2 sales | 3 | 4800 | 2 (10 rows)
SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
depname | empno | salary | avg -----------+-------+--------+----------------------- develop | 11 | 5200 | 5020.0000000000000000 develop | 7 | 4200 | 5020.0000000000000000 develop | 9 | 4500 | 5020.0000000000000000 develop | 8 | 6000 | 5020.0000000000000000 develop | 10 | 5200 | 5020.0000000000000000 personnel | 5 | 3500 | 3700.0000000000000000 personnel | 2 | 3900 | 3700.0000000000000000 sales | 3 | 4800 | 4866.6666666666666667 sales | 1 | 5000 | 4866.6666666666666667 sales | 4 | 4800 | 4866.6666666666666667 (10 rows)
其中rank 可以替換為聚集函數,
SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
salary | sum --------+------- 3500 | 3500 3900 | 7400 4200 | 11600 4500 | 16100 4800 | 25700 4800 | 25700 5000 | 30700 5200 | 41100 5200 | 41100 6000 | 47100 (10 rows)
這里的合計是從第一個(最低的)薪水一直到當前行,包括任何與當前行相同的行(注意相同薪水行的結果)。
窗口函數只允許出現在查詢的SELECT
列表和ORDER BY
子句中。它們不允許出現在其他地方,例如GROUP BY
、HAVING
和WHERE
子句中。這是因為窗口函數的執行邏輯是在處理完這些子句之后。另外,窗口函數在非窗口聚集函數之后執行。這意味着可以在窗口函數的參數中包括一個聚集函數,但反過來不行。
當一個查詢涉及到多個窗口函數時,可以將每一個分別寫在一個獨立的OVER
子句中。但如果多個函數要求同一個窗口行為時,這種做法是冗余的而且容易出錯的。替代方案是,每一個窗口行為可以被放在一個命名的WINDOW
子句中,然后在OVER
中引用它。例如:
SELECT sum(salary) OVER w, avg(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);