用途:在 PostgreSQL 中编写窗口函数查询。窗口函数在不折叠结果集的前提下,跨与当前行相关的行集计算值,写法为 function(args) OVER (PARTITION BY ... ORDER BY ... frame_clause)。PARTITION BY 重置分组窗口,OVER 内的 ORDER BY 定义分区内行序,帧子句决定函数可见的子集。窗口函数只能出现在 SELECT 列表和外层 ORDER BY,不能写入 WHERE、GROUP BY、HAVING,如需按窗口结果过滤应包一层子查询或 CTE。
主要能力:PostgreSQL 提供 ROWS(按物理行计数)、RANGE(按 ORDER BY 列的值范围)、GROUPS(v11+,按对等组计数)三种帧模式。只写 OVER (ORDER BY x) 时默认帧为 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,帧止于当前行的最后一个对等行,这正是 LAST_VALUE 返回当前行的根因;要取分区最后一行需显式写 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。v11 起帧支持 EXCLUDE CURRENT ROW / GROUP / TIES / NO OTHERS。
适用场景与用法要点:累计求和与滑动平均需在 OVER 内写 ORDER BY;每组取前 N 行常用 row_number() OVER (PARTITION BY 分组列 ORDER BY 排序列 DESC),再在外层 WHERE 过滤 rn <= N,因为 WHERE 先于窗口函数执行。行间比较使用 lag/lead 并可通过第三参数指定边界默认值,避免用 id-1 自连接。RANK 在并列处留空位,DENSE_RANK 不留空位,按需选择。NTILE 必须带 ORDER BY,否则分桶顺序不确定。重复的 OVER 子句可用 WINDOW 命名窗口复用。
限制:rank、row_number、dense_rank、percent_rank、cume_dist、ntile 的帧被忽略;first_value、last_value、nth_value 及聚合窗口函数对帧敏感。窗口函数出现在 WHERE、GROUP BY、HAVING 会报错(如 SQLSTATE 42883/42P20)。PostgreSQL 无 IGNORE NULLS,LAG/LEAD 中的 NULL 需预先用 CTE 过滤。RETURNING 不支持窗口函数。版本差异方面,v11 加入 GROUPS 帧与 EXCLUDE,v15 优化了部分排名与计数性能。其余细节暂未提供。