窗口函数疑问:PARTITION BY是否为遍历表的正确方式?SQL查询求助
解决SQL窗口函数查询前后用户名的问题
首先,你的查询无法正常运行的核心问题出在**PARTITION BY username**这个子句上——这完全搞错了窗口函数中分区的作用!
为什么你的原查询不对?
PARTITION BY username会把表中的每一条记录单独划分成一个分区(因为每个username都是唯一的)。在这种情况下,LAG()和LEAD()函数在每个只有一条记录的分区里,根本找不到“前一条”或“后一条”数据,自然返回的都是NULL,完全达不到你想要的效果。
正确的查询语句
你需要去掉PARTITION BY,只保留窗口内的排序规则,因为你的需求是在整个用户表的全局范围内,按字典序找每个用户名的前后项。正确的SQL如下:
SELECT LAG(username, 1) OVER (ORDER BY username) AS before, username, LEAD(username, 1) OVER (ORDER BY username) AS after FROM users ORDER BY username;
预期的正确结果
执行这个查询后,你会得到符合逻辑的结果(修正了你原示例中的笔误):
| before | username | after |
|---|---|---|
| NULL | Grace | Jack |
| Grace | Jack | Niv |
| Jack | Niv | Will |
| Niv | Will | NULL |
关于窗口函数中PARTITION BY的疑问解答
PARTITION BY的作用是将数据集拆分成多个独立的子组,窗口函数只会在每个子组内部进行计算。比如你有一个包含部门和员工的表,想要统计每个部门内员工的薪资排名、前后同事薪资时,才需要用PARTITION BY department来隔离不同部门的数据。
而在你的场景中,我们需要的是全局范围的字典序前后项,不需要拆分分区,所以直接用ORDER BY username定义窗口内的排序规则就足够了。
内容的提问来源于stack exchange,提问作者avi
相关产品推荐
相关产品推荐

