一张结果表既列每位员工,又在旁边重复显示所在部门的平均值,并不一定把部门汇总结果错误地复制了多次。PostgreSQL 17的窗口函数教程,正是用这种结果说明跨行计算与保留当前行身份可以同时发生。要读懂它,需要把计算所看的行,与结果每一行代表什么分别理解。
教程开头说,窗口函数能够针对与当前行相关的一组行进行计算;它与聚合计算有相似之处,却不会像非窗口聚合调用那样把行归成一个输出行。原文强调,行仍保留各自的身份。因此,跨多行得到一个结果,并不总意味着输出必须只剩每组一行。
首个例子使用员工表,前三列仍是部门、员工编号和工资,第四列为同部门员工的平均工资。文档解释,每个表行对应一条输出行,而附加的平均值跨越与当前行具有同一部门名的那些行。同部门的多个员工因此可以分别出现,同时带有相同的部门平均。这里使用的是官方教学例,不是真实薪酬数据或本次执行SQL的结果。
该例的avg后有OVER,内部只写PARTITION BY部门名,没有窗口ORDER BY。教程还专门区分partition与window frame,并指出省略ORDER BY时默认frame包含分区所有行。因此,本文对同部门平均的解释保留这个具体例子,不能把它无条件推广到带有其他排序或frame安排的所有窗口计算。
窗口能看到的行也有前提。教程说明,它面对的是FROM以及适用的WHERE、GROUP BY、HAVING处理后形成的虚拟表;已经被WHERE去掉的行不会重新被窗口函数看到。所以,“窗口保留行身份”不能被改写成任意查询都原样保留源表所有行。输入范围与窗口计算方式仍需要一起阅读。
对数据库结果说明,这一语义能够解释为什么一份输出既有明细身份,又带有跨行统计,而不必先假定发生重复数据错误。本文采用固定PostgreSQL 17教程及相邻范围说明,不提供生产查询修改、DDL或性能结论,也没有连接数据库。它要说明的是这个窗口平均例怎样关联当前行与同部门行,而不是替业务报表决定统计口径。
信息来源
本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。