使用SQL分析函数last_value时是否必须搭配UNBOUNDED FOLLOWING?
问题核心原因
你遇到的返回结果不符合预期的问题,本质是分析函数的默认窗口帧规则导致的,和last_value本身的逻辑无关。
当OVER()子句中声明了ORDER BY但未显式指定窗口范围时,数据库默认采用的窗口帧为:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
也就是窗口范围只会包含从分区起始位置到当前行(排序值和当前行相等的所有行也会被包含,因为是RANGE模式)的内容。你按薪资升序排序时,每一行的窗口都截止到当前行,last_value自然只能取到当前行(或同薪资行)的薪资,不可能拿到全表最高薪资。
核心问题解答
使用last_value时不需要每次都添加UNBOUNDED FOLLOWING,是否添加完全取决于你的业务需求:
- 如果你需要取整个分区/全表的最后一个值:就需要显式把窗口帧的结束边界拉到分区末尾,你写的
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING是可行的,更通用的写法是ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,不受排序方向影响,能稳定拿到整个分区的最后一个值。 - 如果你需要取截止到当前行的窗口最后一个值:直接用默认窗口帧即可,不需要额外声明范围。比如按员工入职时间排序,要统计截至每个员工入职时,最晚入职员工的薪资,默认帧就刚好匹配需求。
额外优化建议
如果你的需求是取全分区的极值,用MAX() OVER()或者FIRST_VALUE() OVER(ORDER BY 字段 DESC)写法的可读性更高,也不容易踩窗口帧的坑,比如你要取全表最高薪资可以直接写:
SELECT employee_id, salary, MAX(salary) OVER() max_salary FROM employees;
内容的提问来源于stack exchange,提问作者Abhilekh Dixit
相关产品推荐
相关产品推荐

