視窗可以定義並給予名稱,以便在 OVER
子句中參照。若要執行此操作,請使用 WINDOW
子句。如果查詢中存在 WINDOW
子句,則 WINDOW
子句會落在 HAVING
和 ORDER BY
子句之間的位置,且具有以下語法
WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...
對於每個視窗定義,window_name
是視窗名稱,而 window_spec
則與 OVER
子句的括號之間所給定的視窗規格類型相同,如第 14.20.2 節「視窗函數概念和語法」所述
window_spec:
[window_name] [partition_clause] [order_clause] [frame_clause]
WINDOW
子句對於多個 OVER
子句會以其他方式定義相同視窗的查詢很有用。您可以使用定義一次視窗,給予名稱,並在 OVER
子句中參照該名稱。請考量以下查詢,其多次定義相同的視窗
SELECT
val,
ROW_NUMBER() OVER (ORDER BY val) AS 'row_number',
RANK() OVER (ORDER BY val) AS 'rank',
DENSE_RANK() OVER (ORDER BY val) AS 'dense_rank'
FROM numbers;
使用 WINDOW
定義一次視窗,並在 OVER
子句中依名稱參照視窗,即可更簡單地撰寫查詢
SELECT
val,
ROW_NUMBER() OVER w AS 'row_number',
RANK() OVER w AS 'rank',
DENSE_RANK() OVER w AS 'dense_rank'
FROM numbers
WINDOW w AS (ORDER BY val);
具名視窗也讓實驗視窗定義以查看對查詢結果的影響更加容易。您只需要修改 WINDOW
子句中的視窗定義,而不是多個 OVER
子句定義。
如果 OVER
子句使用 OVER (
而不是 window_name
...)OVER
,則可以透過新增其他子句來修改具名視窗。例如,此查詢定義包含分割區的視窗,並在 window_name
OVER
子句中使用 ORDER BY
以不同方式修改視窗
SELECT
DISTINCT year, country,
FIRST_VALUE(year) OVER (w ORDER BY year ASC) AS first,
FIRST_VALUE(year) OVER (w ORDER BY year DESC) AS last
FROM sales
WINDOW w AS (PARTITION BY country);
OVER
子句只能將屬性新增至具名視窗,而不能修改屬性。如果具名視窗定義包含分割區、排序或框架屬性,則參照視窗名稱的 OVER
子句也不能包含相同種類的屬性,否則會發生錯誤
允許此結構,因為視窗定義和參照的
OVER
子句不包含相同種類的屬性OVER (w ORDER BY country) ... WINDOW w AS (PARTITION BY country)
不允許此結構,因為
OVER
子句為已具有PARTITION BY
的具名視窗指定PARTITION BY
OVER (w PARTITION BY year) ... WINDOW w AS (PARTITION BY country)
具名視窗的定義本身可以 window_name
開始。在這種情況下,允許向前和向後參照,但不允許循環
允許這樣做;它包含向前和向後參照,但沒有循環
WINDOW w1 AS (w2), w2 AS (), w3 AS (w1)
不允許這樣做,因為它包含循環
WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1)