为何无法在单条SELECT语句中结合RANK()与WHERE条件使用?
为什么直接在SELECT语句中引用窗口函数别名会报错?
我可以通过以下查询为每个分组计算排名并定义别名rk:
SELECT *, RANK() OVER (PARTITION BY some_field ORDER BY value) AS rk FROM my_table
查询结果:
| some_field | value | rk |
|---|---|---|
| same | 10 | 1 |
| same | 20 | 2 |
| same | 30 | 3 |
尝试直接在WHERE子句中引用rk过滤时:
SELECT *, RANK() OVER (PARTITION BY some_field ORDER BY value) AS rk FROM my_table WHERE rk = 1
会得到报错:column "rk" does not exist
但使用子查询就能正常运行:
SELECT * FROM ( SELECT *, RANK() OVER (PARTITION BY some_field ORDER BY value) AS rk FROM my_table ) AS t WHERE rk = 1
查询结果:
| some_field | value | rk |
|---|---|---|
| same | 10 | 1 |
原因解析
这和窗口函数本身无关,核心是SQL的执行顺序:
- SQL语句会先执行
FROM和WHERE子句,这一步是从原始表中筛选数据,此时SELECT子句里定义的别名(包括窗口函数生成的rk)还没有被创建出来,所以WHERE无法识别这个列。 - 子查询的方式中,内层
SELECT会先执行,生成包含rk列的临时结果集,之后外层的WHERE是对这个已经存在rk列的临时表进行过滤,自然就能识别到rk了。
内容的提问来源于stack exchange,提问作者Chris Kao
相关产品推荐
相关产品推荐

