文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
手冊頁 (TGZ) - 258.5Kb
手冊頁 (Zip) - 365.5Kb
資訊 (Gzip) - 4.0Mb
資訊 (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  具名視窗

14.20.4 具名視窗

視窗可以定義並給予名稱,以便在 OVER 子句中參照。若要執行此操作,請使用 WINDOW 子句。如果查詢中存在 WINDOW 子句,則 WINDOW 子句會落在 HAVINGORDER 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)