Oracle中SELECT语句ORDER BY NAME列返回错误排序问题求助
Oracle VARCHAR2列降序排序不符合预期的解决方法
问题根源
你执行ORDER BY NAME DESC得到的结果不符合预期,本质是Oracle默认采用二进制(BINARY)排序规则:
- ASCII编码中,大写字母(A-Z,对应65-90)的数值小于小写字母(a-z,对应97-122)
- 降序排序时数值大的字符优先,导致大写字母会整体排在对应小写字母的前面(比如
H的ASCII值是72,f是102,二进制降序会让H排在f之前),最终出现排序逻辑混乱的情况。
解决方案
方法1:统一大小写后排序(无需修改系统参数)
通过UPPER()或LOWER()函数将NAME列转换为统一大小写后排序,既保证排序逻辑符合预期,又保留原字段的显示内容:
SELECT * FROM L5_ORDERBY ORDER BY UPPER(NAME) DESC, NAME DESC;
- 外层
UPPER(NAME) DESC实现不区分大小写的降序排序 - 内层
NAME DESC保证相同字母的大小写间仍按降序排列(小写在前,大写在后)
若不需要区分大小写的内部排序,可简化为:
SELECT * FROM L5_ORDERBY ORDER BY UPPER(NAME) DESC;
方法2:修改会话级排序规则(全局生效)
通过修改会话参数,启用不区分大小写的排序规则(BINARY_CI,CI代表Case Insensitive):
ALTER SESSION SET NLS_SORT = BINARY_CI; ALTER SESSION SET NLS_COMP = LINGUISTIC;
执行以上语句后,再运行原查询SELECT * FROM L5_ORDERBY ORDER BY NAME DESC,即可得到不区分大小写的排序结果。
如果需要永久生效,可修改数据库级的NLS_SORT和NLS_COMP参数,或在创建表时为NAME列指定排序规则:
CREATE TABLE L5_ORDERBY ( LVL NUMBER, NAME VARCHAR2(10) COLLATE BINARY_CI );
内容的提问来源于stack exchange,提问作者Bayram Yusifov
相关产品推荐
相关产品推荐

