You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL中LAST_VALUE()窗口函数使用RANGE边界未按预期返回结果的问题咨询

SQL中LAST_VALUE()窗口函数使用RANGE边界未按预期返回结果的问题咨询

嘿,我来帮你搞明白这个问题!先把你的场景和核心疑问理清楚:

你运行了这段SQL查询:

select e.first_name ,
e.last_name,
ed.department_name ,
e.salary,
last_value(concat(e.first_name, ' ', e.last_name)) over(partition by ed.department_name order by salary range between unbounded preceding and unbounded following) UnboundedCol,
last_value(concat(first_name, ' ', last_name)) over(partition by ed.department_name order by salary range between 0 preceding and 0 following) range0,
last_value(concat(first_name, ' ', last_name)) over(partition by ed.department_name order by salary range between 1 preceding and 1 following) range1,
last_value(concat(first_name, ' ', last_name)) over(partition by ed.department_name order by salary range between 2 preceding and 2 following) range2,
last_value(concat(first_name, ' ', last_name)) over(partition by ed.department_name order by salary range between 3 preceding and 3 following) range3
from employees e
join employee_departments ed on e.department_id = ed.department_id
order by ed.department_name, salary;

你发现在Finance部门里,比如Jose Manuel Urman那一行,range1列的结果还是他自己,但你预期应该是下一行的John Chen——你以为range between 1 preceding and 1 following是取前后各1行,但实际结果和range0完全一致,这到底是怎么回事?

核心原因:你混淆了RANGE和ROWS的窗口边界逻辑!

RANGE不是按行数来计算窗口的,而是按排序列的数值范围!

拿你的例子拆解:

  • Jose Manuel的salary是7800
  • range between 1 preceding and 1 following的真实含义是:salary值在7800-1到7800+1之间的所有行,也就是7799 ≤ salary ≤7801
  • 看Finance部门的salary列表:上一行是7700,下一行是8200——这两个数值都不在7799-7801的区间里,所以这个窗口里只有Jose Manuel自己一行
  • 那LAST_VALUE()自然就只能返回他自己了

而你说用ROWS模式正常,是因为ROWS才是按行的位置偏移计算窗口:rows between 1 preceding and 1 following就是取当前行的前1行、当前行、后1行,这时候窗口里包含了John Chen,LAST_VALUE()就会返回窗口里最后一行的他。

再举个例子帮你加深理解

假设Finance部门里有另一个员工,salary是7801,那Jose Manuel的range1窗口就会包含这个员工——这时候LAST_VALUE()就会返回这个salary7801的员工(因为按salary排序,他在Jose Manuel后面)。

关键知识点总结

  • RANGE:基于排序列的数值范围划分窗口,N preceding/following是指当前行排序列值±N的区间
  • ROWS:基于行的位置偏移划分窗口,N preceding/following是指前后N行

这就是为啥你用RANGE的时候,range0到range3结果都一样——因为你的salary值之间的差距远大于1、2、3,所以这些范围里都只有当前行自己。

备注:内容来源于stack exchange,提问作者DumbCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 10:17:59