LeetCode178.分数排名SQL查询中rank别名相关报错原因咨询
LeetCode 178. Rank Scores 子查询写法异常原因说明
可正常运行的参考代码
select score, (select count(distinct s1.score) from scores s1 where s1.score > s2.score)+1 as 'rank' from scores s2 order by s2.score desc;
两个异常现象的具体原因
1. 别名去掉单引号直接写rank触发报错的原因
RANK是SQL标准(MySQL 8.0及以上版本已全面支持)中的保留关键字,对应内置的RANK()窗口函数,用于实现分区排名逻辑。
SQL解析器处理语句时,会优先将未加标识符引用的rank识别为内置函数名,而非自定义列别名,直接触发语法解析冲突。给rank加上引号后,相当于告知解析器这是用户自定义的别名,不属于内置关键字范畴,因此不会触发解析错误。
注:MySQL中标准的标识符引用符号是反引号
`,单引号包裹别名能正常运行是宽松SQL模式下的兼容行为,并非标准写法。
2. 写order by rank触发报错、order by score正常运行的原因
这个现象由两个解析规则共同导致:
- 首先,不带任何引号的
rank本身是保留关键字,解析器不会将其识别为普通列引用; - 其次,定义别名时使用单引号包裹
'rank',在SQL解析逻辑中单引号的作用是包裹字符串字面量,而非定义标识符别名。这种写法虽然能在最终返回结果中把列名显示为rank,但SELECT阶段并没有将其注册为可被后续子句(ORDER BY/GROUP BY等)引用的合法列别名,因此ORDER BY阶段找不到名为rank的可排序列。
而score是scores表的原生字段名,不属于保留关键字,不管是直接引用原表字段,还是匹配SELECT子句查询出的列,都能被解析器正常识别,因此可以正常用于排序。
如果要让order by rank正常生效,只需要把别名的单引号换成MySQL标准的标识符引用反引号即可,修改后写法如下:
select score, (select count(distinct s1.score) from scores s1 where s1.score > s2.score)+1 as `rank` from scores s2 order by `rank` desc;
内容的提问来源于stack exchange,提问作者Tushar SINGH
相关产品推荐
相关产品推荐

