文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

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)