首页/数据/SQL 速查/WINDOW 子句命名窗口
聚合与窗口函数54 条

WINDOW 子句命名窗口

多个窗口函数复用同一 OVER 定义时,用 WINDOW 子句命名,减少重复与笔误;MySQL 8 与 PostgreSQL 都支持。

SQL 速查数据更新于 2026-10-13

给窗口起个名字

一个查询里多个窗口函数用同一个 OVER 定义时,可以用 WINDOW 子句给窗口命名,再在函数后面引用名称:少写重复的 PARTITION BY 与 ORDER BY,改一处全生效。MySQL 8 与 PostgreSQL 都支持这种写法。

基本信息

语法WINDOW 名称 AS (定义),一个查询可定义多个
引用方式在函数后写 OVER 名称
收益同一查询内复用,修改只需改一处
能力限制命名窗口不能再改 PARTITION BY;能否追加 ORDER BY 视数据库而定
作用域仅限当前查询,子查询里要重新定义

典型使用场景

  • 一次算多个指标,例如组内均值、组内最大值
  • 计算与组均值的差值
  • 避免重复粘贴同一段窗口定义
  • 统一团队 SQL 的窗口写法
  • 横向对比不同窗口定义的效果

示例

示例
SELECT id, dept_id, salary,
       AVG(salary) OVER w AS dept_avg,
       MAX(salary) OVER w AS dept_max,
       salary - AVG(salary) OVER w AS diff
FROM employees
WINDOW w AS (PARTITION BY dept_id);

-- 一个查询里可以定义多个命名窗口
SELECT id, dept_id, salary,
       AVG(salary) OVER w_dept AS dept_avg,
       AVG(salary) OVER w_all  AS global_avg
FROM employees
WINDOW w_dept AS (PARTITION BY dept_id),
       w_all  AS ();

能力边界

能力是否支持说明
引用命名窗口支持函数后写 OVER 名称即可
追加 ORDER BY视数据库而定部分实现允许在名称后补排序
再改 PARTITION BY不支持分区必须写在名称定义里
跨子查询复用不支持作用域只在当前查询
整分区窗口支持WINDOW w AS () 表示不分区
命名窗口不等于缓存结果:它只是语法层面的复用,函数仍按各自的帧逐行计算,性能和把定义展开写没有本质差别。
作用域只在当前查询:把这套写法搬到子查询里必须重新定义,否则会报找不到窗口名。
命名窗口也能用在聚合窗口函数上:同一查询里同时算组内累计与组内总额,用两个命名窗口比把定义重复写四遍清楚得多。
团队里可以把常用的窗口定义整理成片段随 SQL 一起提交,评审时几秒就能看出分组与排序口径是否一致,比读散落在多处的 OVER 定义快得多。

易错点

  • 在命名窗口上再叠加新的 PARTITION BY:不支持会直接报错,分区必须写在定义里
  • 命名窗口跨子查询引用:作用域只在当前查询,子查询里要重新定义
  • 以为命名窗口能缓存计算结果:它只是语法复用,函数仍逐行计算
  • 把追加排序的能力照搬到不同数据库:各库限制不同,写之前先验证
  • 窗口定义与业务分组不一致:同一别名被用在语义不同的分组上,结果看似合理实则错配

数据来源与参考

  • MySQL 8.0 Reference Manual · Window Functions · WINDOW Clause
  • PostgreSQL Documentation · SELECT · WINDOW Clause
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌