Union查询排序问题:如何获取指定ID前后各2条有序数据
修正方案及原理
你的问题出在UNION ALL不会保留子查询的排序结果——SQL标准中,只有最外层的ORDER BY才能保证最终结果的顺序,子查询里的ORDER BY仅用于配合LIMIT筛选数据,不影响合并后的整体顺序。
方法一:合并后统一排序(最稳妥)
将两个子查询的结果合并后,在外层添加ORDER BY id ASC,确保整体按ID升序排列:
SELECT * FROM ( SELECT * FROM $table WHERE id < $skip ORDER BY id DESC LIMIT 2 UNION ALL SELECT * FROM $table WHERE id > $skip ORDER BY id ASC LIMIT 2 ) AS combined_data ORDER BY id ASC;
执行后会得到你期望的4 - 5 - 8 - 9(注:你的ID序列中无7,推测是笔误)顺序。
方法二:调整前半段子查询的排序逻辑
如果不想外层排序,也可以先对前半段的筛选结果单独排序后再合并,但需注意部分数据库可能仍需要外层排序来保证最终顺序,写法如下:
SELECT * FROM ( SELECT * FROM $table WHERE id < $skip ORDER BY id DESC LIMIT 2 ) AS prev_records ORDER BY id ASC UNION ALL SELECT * FROM $table WHERE id > $skip ORDER BY id ASC LIMIT 2;
为什么之前的嵌套排序无效?
你尝试的嵌套排序((SELECT ... ORDER BY id DESC LIMIT 2) ORDER BY id ASC),这个内层的ORDER BY确实会让前半段子查询返回4、5,但一旦用UNION ALL和后半段拼接,数据库不会保证前半段的顺序被保留——除非在外层明确指定排序规则,否则结果顺序是不确定的。
内容的提问来源于stack exchange,提问作者Tripple Delta
相关产品推荐
相关产品推荐

