SQL代码运行异常:每次执行返回结果不一致(附代码)
问题原因
- 子查询里的
ORDER BY sname ASC无效:MySQL中,派生表(即这里的temp表)的ORDER BY如果不搭配LIMIT,优化器会直接忽略这个排序规则。这就导致ROW_NUMBER()按age分区后,组内记录的顺序没有固定依据,每次执行时rn的分配结果都会随机变化。 - 排序键存在重复值:就算子查询的
ORDER BY生效,若同一个age组内有多个sname相同的记录,仅靠sname ASC无法确定唯一排序顺序,数据库会自行选择隐含的排序依据(比如数据存储顺序),而这些依据在不同执行场景下可能发生变动,最终导致查询结果不稳定。
修复方案
把排序条件整合到ROW_NUMBER()的OVER()子句中,让分区内的排序逻辑固定下来,修改后的SQL如下:
Select * from (SELECT * , ROW_NUMBER() OVER(PARTITION BY age ORDER BY sname ASC) as rn FROM `usr` ) temp where rn = 2 and location = "Sz"
如果需要更严格的结果稳定性(比如sname重复时也能锁定唯一结果),可以添加一个唯一标识列(比如表的主键id)作为第二排序条件:
Select * from (SELECT * , ROW_NUMBER() OVER(PARTITION BY age ORDER BY sname ASC, id ASC) as rn FROM `usr` ) temp where rn = 2 and location = "Sz"
这样每次执行时,同年龄组内的记录排序顺序完全固定,rn=2对应的记录也不会再出现变化。
内容的提问来源于stack exchange,提问作者Thaviraj Junglee
相关产品推荐
相关产品推荐

