Oracle 10中如何将UNION查询结果中的'(None)'始终排在首位?
解决方案:让'(None)'始终排在结果集首位
要解决Oracle 10中这个排序问题,不用加空格这种临时hack手段,最稳妥的方式是给排序逻辑增加一个优先级控制规则,让'(None)'行拥有最高的排序优先级。
修改后的SQL语句(带显式排序字段)
SELECT -1 AS ID, '(None)' AS NAME, 0 AS SORT_ORDER FROM TABLE_1 WHERE ID=1 UNION SELECT ID, NAME, 1 AS SORT_ORDER FROM TABLE_2 ORDER BY SORT_ORDER, NAME;
逻辑解释
- 给两个查询分支分别添加一个
SORT_ORDER字段:- 包含'(None)'的分支设为
0(最高优先级) - 正常数据分支设为
1(次优先级)
- 包含'(None)'的分支设为
- 排序时先按
SORT_ORDER升序排列,这样0的行必然排在最前面;之后再按NAME字段排序,保证其他数据的原有排序逻辑。
执行结果验证
用你提供的表数据,执行后会得到符合预期的结果:
ID | NAME -1 | (None) 1 | Direct 3 | Etc 2 | Personal
为什么原来的方法失效?
你原来的ORDER BY 2是直接按NAME字段排序,而Oracle的字符排序依赖于数据库的字符集配置,'(None)'中的括号(在很多字符集中的排序权重比字母靠后,所以会被排到后面。加空格的方法属于临时hack,一旦字符集调整或者后续出现带空格的NAME值,就会失效。
更简洁的等价写法(无需额外字段)
如果不想暴露额外的排序字段,也可以把优先级逻辑直接写在ORDER BY子句里:
SELECT -1 AS ID, '(None)' AS NAME FROM TABLE_1 WHERE ID=1 UNION SELECT ID, NAME FROM TABLE_2 ORDER BY CASE WHEN NAME = '(None)' THEN 0 ELSE 1 END, NAME;
这种写法不需要添加新字段,效果和上面完全一致,适合不需要暴露排序逻辑的场景。
内容的提问来源于stack exchange,提问作者Athris
相关产品推荐
相关产品推荐

