SQL Server中排序字段值相同时ROW_NUMBER()结果是否稳定可靠?
SQL Server中ROW_NUMBER()排序字段重复时的结果稳定性问题
当updDtm和fileCreatedTime字段值完全相同时,你当前的查询结果不保证重复可靠,多次执行可能返回不同的id,并非固定返回id=1。
原因说明
ROW_NUMBER()需要为每行生成唯一序号,但如果ORDER BY子句里的字段没有足够区分度,SQL Server的查询优化器会根据执行计划的变化(比如索引选择、数据物理存储顺序变动等),给相同排序键的行分配不同的序号。主键id虽然唯一,但你没把它加入排序逻辑,SQL Server不会默认用主键作为排序兜底依据。
解决方法
要让结果稳定可重复,必须在ORDER BY中加入唯一标识字段(比如主键id)消除排序歧义。如果你的“最新账户”逻辑是取最大的id,修改后的SQL如下:
SELECT t.id FROM (SELECT ROW_NUMBER() OVER(PARTITION BY a.accno ORDER BY a.updDtm desc, a.fileCreatedTime DESC, a.id DESC) AS seq, a.id, a.accno, a.updDtm, a.fileCreatedTime FROM test_account a) AS t WHERE t.seq = 1
如果需要最小id,把a.id DESC改成a.id ASC即可,这样每次执行结果都会一致。
和MySQL、Oracle的对比
和你了解的情况一致,MySQL、Oracle在遇到类似排序键重复的场景时,同样无法保证窗口函数结果的稳定性,必须通过加入唯一字段来确保结果可靠。
内容的提问来源于stack exchange,提问作者Lei
相关产品推荐
相关产品推荐

