为何FIRST_VALUE与LAST_VALUE默认数据窗口表现存在差异?
关于窗口函数FIRST_VALUE/LAST_VALUE默认窗口框架的问题解答
嘿,这个坑我之前踩过!其实核心原因是窗口函数的默认框架规则跟你想的不一样,尤其是当窗口里指定了ORDER BY的时候。
先明确关键规则:
当你在窗口函数的OVER()子句里添加了ORDER BY,SQL的默认窗口框架是:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
而不是你以为的整个数据集(UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)。只有当窗口里没有ORDER BY的时候,默认框架才是覆盖整个分区的。
拆解你的现象:
FIRST_VALUE看起来用了全窗口
因为FIRST_VALUE是取窗口框架内的第一行数据。当框架是UNBOUNDED PRECEDING AND CURRENT ROW时,不管当前行是第几行,框架的起始都是排序后的第一行,所以每次返回的都是整个有序集的第一个WEEK值,看起来就像是用了全窗口的范围。LAST_VALUE只返回当前行
同样基于默认框架UNBOUNDED PRECEDING AND CURRENT ROW,框架的结尾是当前行,所以LAST_VALUE只能取到当前行的WEEK值——相当于框架被限制在了当前行本身,所以你会觉得它的默认窗口是CURRENT_ROW AND CURRENT_ROW。
解决方法:
如果你想让LAST_VALUE返回整个有序窗口的最后一个值,需要显式指定窗口框架,比如:
LAST_VALUE(to_char(INVOICEDATE,'iw')) OVER ( ORDER BY SUM(total) RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) max_2
这样就能让LAST_VALUE遍历整个排序后的数据集,拿到最后一行的WEEK值了。
内容的提问来源于stack exchange,提问作者misza2000
相关产品推荐
相关产品推荐

