首页 数据库 mysql教程 oracle 使用order by 对汉字进行多字段排序

oracle 使用order by 对汉字进行多字段排序

Jun 07, 2016 pm 03:37 PM
oracle order 使用 字段 排序 汉字 进行

今天遇到一个奇怪的问题, 在两个不同的数据库里执行同样的sql语句, 相同的数据却排序结果不一致。 执行sql如下: select decode(brch.LOCAL, 'Y', '国内', '国际') as local, brch.COUNTRY, brch.PROVINCE, brch.CITY, brch.AREA, brch.VENDOR, brch.SERVI

今天遇到一个奇怪的问题, 在两个不同的数据库里执行同样的sql语句, 相同的数据却排序结果不一致。

 

执行sql如下:

select decode(brch.LOCAL, 'Y', '国内', '国际') as local,
brch.COUNTRY,
brch.PROVINCE,
brch.CITY,
brch.AREA,
brch.VENDOR,
brch.SERVICE_PROVIDER,
brch.SERVICE_SITE_ADDR
from lpmsrepdata.vip_sx_service_site_brch brch
where brch.type_cd = 'TJJG'
and brch.active_flg = 'Y'
AND brch.PROVINCE = trim('湖北')
order by brch.local,
brch.country,
brch.province,
brch.city,
brch.area,
brch.service_provider,
brch.service_site_addr asc

执行结果分别为;

1.

LOCAL COUNTRY                                                               PROVINCE                                                              CITY                                                                         AREA                                                                       VENDOR                                                                 SERVICE_PROVIDER                                              SERVICE_SITE_ADDR
------ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
国内 中国                                                                          湖北                                                                          武汉市                                                                      汉阳区                                                                                                                                                       美年大健康-武汉美年(原一博体检中心)            武汉市汉阳区二桥路19号汉江阳光城1-2层(原一博体检中心)
国内 中国                                                                          湖北                                                                          武汉市                                                                      江岸区                                                                                                                                                       美年大健康-武汉美年                                              武汉市江岸区黄孝河路107号花桥大厦1-3楼(原梦天湖大酒店)
国内 中国                                                                          湖北                                                                          武汉市                                                                      武昌区                                                                                                                                                       美年大健康-武汉美年                                              武汉市武昌区中北路108号广泽中心4F
 

2.


LOCAL COUNTRY                                                               PROVINCE                                                              CITY                                                                         AREA                                                                       VENDOR                                                                 SERVICE_PROVIDER                                              SERVICE_SITE_ADDR
------ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
国内 中国                                                                          湖北                                                                          武汉市                                                                      武昌区                                                                                                                                                       美年大健康-武汉美年                                              武汉市武昌区中北路108号广泽中心4F
国内 中国                                                                          湖北                                                                          武汉市                                                                      汉阳区                                                                                                                                                       美年大健康-武汉美年(原一博体检中心)            武汉市汉阳区二桥路19号汉江阳光城1-2层(原一博体检中心)
国内 中国                                                                          湖北                                                                          武汉市                                                                      江岸区                                                                                                                                                       美年大健康-武汉美年                                              武汉市江岸区黄孝河路107号花桥大厦1-3楼(原梦天湖大酒店)
 

查了下, oracle对于order  by的排序规则

Oracle provides the following types of sorts:
Binary sort
Monolingual linguistic sort
Multilingual linguistic sort
注:后两种可统一为linguistic(语言的) sort

 

而在汉语里,

Chinese is how to sort?

Prior to Oracle9i, the Chinese are in accordance with the sort of binary encoding.
Added in oracle9i in accordance with pinyin, radical, stroke order functions. Set NLS_SORT value
SCHINESE_RADICAL_M in accordance with the radical (first order), stroke (second order) Sort
SCHINESE_STROKE_M in accordance with the stroke (first order), radicals (second order) Sort
SCHINESE_PINYIN_M sorted according to Pinyin

所以在排序时需要考虑;排序综合考虑数据库字符集、NLS_SORT

 

 

查看数据库的字符集;

SQL> select * from v$nls_parameters  where  PARAMETER like '%NLS_CHARACTERSET%';
 
PARAMETER                                          VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_CHARACTERSET                           AL32UTF8

 

SQL> select * from v$nls_parameters  where  PARAMETER like '%NLS_CHARACTERSET%';
 
PARAMETER                                          VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_CHARACTERSET                           ZHS16GBK
 
SQL>

 

如果字符集为ZHS16GBK/ZH16GBK,那么使用order by默认是按照汉字的拼音顺序进行排序的;如果为其他(如UTF8),那么汉字的排序是按照BINARY排序的。

数据库字符集不为中文字符集的情况下怎样让其按照汉字拼音排序?答案是设置NLS_SORT

果然不一样,但是nls_sort确实一样的。

SQL> select value from nls_database_parameters where parameter='NLS_SORT'; 
 
VALUE
--------------------------------------------------------------------------------
BINARY

 

SQL> select value from nls_database_parameters where parameter='NLS_SORT'; 
 
VALUE
--------------------------------------------------------------------------------
BINARY


字符集为中文字符集、NLS_SORT为BINARY时,汉字是按汉字拼音排序;
字符集为非中文字符集(如UTF8)、NLS_SORT为BINARY时,汉字按二进制编码(BINARY)排序。
所以,对非中文字符集库: 可通过设置其NLS_SORT来实现汉字的定制化排序;改变当前会话的NLS_SORT:

ALTER session SET NLS_SORT = SCHINESE_PINYIN_M  ;

再看下结果,就都一致了..

LOCAL COUNTRY                                           PROVINCE                                          CITY                                                     AREA                                                   VENDOR                                             SERVICE_PROVIDER                          SERVICE_SITE_ADDR
----- ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ --------------------------------------------------------------------------------
国内 中国                                                      湖北                                                      武汉市                                                  汉阳区                                                                                                               美年大健康-武汉美年(原一博体检中心) 武汉市汉阳区二桥路19号汉江阳光城1-2层(原一博体检中心)
国内 中国                                                      湖北                                                      武汉市                                                  江岸区                                                                                                               美年大健康-武汉美年                          武汉市江岸区黄孝河路107号花桥大厦1-3楼(原梦天湖大酒店)
国内 中国                                                      湖北                                                      武汉市                                                  武昌区                                                                                                               美年大健康-武汉美年                          武汉市武昌区中北路108号广泽中心4F
 

 

LOCAL COUNTRY                                           PROVINCE                                          CITY                                                     AREA                                                   VENDOR                                             SERVICE_PROVIDER                          SERVICE_SITE_ADDR
----- ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ --------------------------------------------------------------------------------
国内 中国                                                      湖北                                                      武汉市                                                  汉阳区                                                                                                               美年大健康-武汉美年(原一博体检中心) 武汉市汉阳区二桥路19号汉江阳光城1-2层(原一博体检中心)
国内 中国                                                      湖北                                                      武汉市                                                  江岸区                                                                                                               美年大健康-武汉美年                          武汉市江岸区黄孝河路107号花桥大厦1-3楼(原梦天湖大酒店)
国内 中国                                                      湖北                                                      武汉市                                                  武昌区                                                                                                               美年大健康-武汉美年                          武汉市武昌区中北路108号广泽中心4F
 


看下如下:

Prior to Oracle9i, the Chinese is based on binary coding to sort. The oracle9i added in accordance with the phonetic, radical, stroke sorting.
1, set parameter values NLS_SORT
SCHINESE_RADICAL_M accordance with the radical (first order), stroke (second order) to sort
SCHINESE_STROKE_M accordance with the stroke (first order), radical (second order) to sort
SCHINESE_PINYIN_M sorted according to Pinyin
2, Session-level settings, modify the default ORACLE field Sort by:
According to Pinyin: alter session set nls_sort = SCHINESE_PINYIN_M;
According to stroke: alter session set nls_sort = SCHINESE_STROKE_M;
According to the radical: alter session set nls_sort = NLS_SORT = SCHINESE_RADICAL_M;
3, the statement level is set Sort by:
Oracle according to alphabetical order
Select * From [tablename] order By nlssort (colname, 'NLS_SORT = SCHINESE_STROKE_M');
Oracle accordance with the radical sort
Select * From [tablename] order By nlssort (colname, 'NLS_SORT = SCHINESE_RADICAL_M');
Oracle sorted according to Pinyin
Select * From [tablename] order By nlssort (colname, 'NLS_SORT = SCHINESE_PINYIN_M');
4, modify the system parameters (database where the operating system):
set NLS_SORT = SCHINESE_RADICAL_M; export NLS_SORT (sh)
setenv NLS_SORT SCHINESE_RADICAL_M (csh)
HKLC \ SOFTWARE \ ORACLE \ home0 \ NLS_SORT (win registry)

 

引用其他人的实验:

如果数据库字符集选用的是ZH16GBK,那么使用order by默认是按照汉字的拼音顺序进行排序的。有方法改变这个默认规则么?
答案是肯定的,Oracle针对简体中文提供三种排序方法,主要是围绕“拼音”、“部首”和“笔画数”展开的。
通过实验,给大家展示一下NLSSORT在改变简体汉字排序规则方面的魅力。

1.在Oracle的官方文档中关于排序有如下描述
“Linguistic Sorts”
http://download.oracle.com/docs/cd/B19306_01/server.102/b14225/applocaledata.htm#sthref2000
其中表“Table A-15 Multilingual LInguistic Sorts”中我们关注一下有关中文排序的内容(前三条与简体中文排序有关,后两条与繁体中文排序有关):
1)SCHINESE_RADICAL_M
Simplified Chinese sort based on radical as primary order and number of strokes order as secondary order
注释:简体中文按照第一顺序是“部首”第二顺序是“笔画数”进行排序;

2)SCHINESE_STROKE_M
Simplified Chinese sort uses number of strokes as primary order and radical as secondary order
注释:简体中文按照第一顺序“笔画数”是第二顺序是“部首”进行排序;

3)SCHINESE_PINYIN_M
Simplified Chinese PinYin sorting order
注释:简体中文按照“拼音”进行排序;

4)TCHINESE_RADICAL_M
Traditional Chinese sort based on radical as primary order and number of strokes order as secondary order
注释:繁体中文按照第一顺序是“部首”第二顺序是“笔画数”进行排序;

5)TCHINESE_STROKE_M
Traditional Chinese sort uses number of strokes as primary order and radical as secondary order. It supports supplementary characters.
注释:繁体中文按照第一顺序“笔画数”是第二顺序是“部首”进行排序;

2.创建实验表T,并初始化六条记录
sec@secooler> create table t (x varchar2(10));
sec@secooler> insert into t values ('侯');
sec@secooler> insert into t values ('你');
sec@secooler> insert into t values ('做');
sec@secooler> insert into t values ('拉');
sec@secooler> insert into t values ('推');
sec@secooler> insert into t values ('拆');
sec@secooler> commit;
sec@secooler> select * from t;

X
------------------------------







6 rows selected.

3.确认数据库版本和数据库字符集
sec@secooler> select * from v$version;

BANNER
----------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

sec@secooler> select userenv('language') from dual;

USERENV('LANGUAGE')
-----------------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

4.在此环境下,查看默认的汉字排序规则
sec@secooler> select * from t order by x;

X
------------------------------







6 rows selected.

可见,此时的默认汉字排序规则是“拼音”。

5.使用nlssort强制按照拼音排序的方法
sec@secooler> select * from t order by nlssort(x,'NLS_SORT=SCHINESE_PINYIN_M');

X
------------------------------







6 rows selected.

6.使用nlssort强制按照“部首”(第一顺序)和“笔画数”(第二顺序)排序的方法
sec@secooler> select * from t order by nlssort(x,'NLS_SORT=SCHINESE_RADICAL_M');

X
------------------------------







6 rows selected.

单人旁的汉字在前,提手旁汉字在后;单人旁的三个汉字进一步又是按照笔画数多少进行的排序。

7.使用nlssort强制按照“笔画数”(第一顺序)和“部首”(第二顺序)排序的方法
sec@secooler> select * from t order by nlssort(x,'NLS_SORT=SCHINESE_STROKE_M');

X
------------------------------







6 rows selected.

可见,越往后的汉字的笔画数越多。

8.Oracle官方文档中关于NSLSORT函数的描述参考
http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/functions111.htm#SQLRF00678

9.小结
NSLSORT函数在国际化支持上提供了一个非常好的排序解决方案。在具体应用环境下有其重要的意义。善用之。

 

 

 

 

 

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

oracle数据库日志会保存多久 oracle数据库日志会保存多久 May 10, 2024 am 03:27 AM

Oracle 数据库日志的保留期限取决于日志类型和配置,包括:重做日志:由 "LOG_ARCHIVE_DEST" 参数配置的最大大小决定。归档重做日志:由 "DB_RECOVERY_FILE_DEST_SIZE" 参数配置的最大大小决定。在线重做日志:不归档,在数据库重启时丢失,保留期限与实例运行时间一致。审计日志:由 "AUDIT_TRAIL" 参数配置,默认保留 30 天。

oracle中计算两个日期之间天数的函数 oracle中计算两个日期之间天数的函数 May 08, 2024 pm 07:45 PM

Oracle 中计算两个日期之间天数的函数是 DATEDIFF()。具体用法如下:指定时间间隔单位:interval(如 day、month、year)指定两个日期值:date1 和 date2DATEDIFF(interval, date1, date2) 返回天数差

oracle数据库启动步骤顺序为 oracle数据库启动步骤顺序为 May 10, 2024 am 01:48 AM

Oracle 数据库启动顺序为:1. 检查前置条件;2. 启动监听器;3. 启动数据库实例;4. 等待数据库打开;5. 连接到数据库;6. 验证数据库状态;7. 启用服务(如果需要);8. 测试连接。

oracle中interval的用法 oracle中interval的用法 May 08, 2024 pm 07:54 PM

Oracle 中的 INTERVAL 数据类型用于表示时间间隔,语法为 INTERVAL <精度> <单位>,可使用加减乘除运算操作 INTERVAL,适用于存储时间数据、计算日期差值等场景。

oracle中某个字符出现的次数怎么看出来 oracle中某个字符出现的次数怎么看出来 May 09, 2024 pm 09:33 PM

要在 Oracle 中查找字符出现的次数,执行以下步骤:获取字符串的总长度;获取字符所在子字符串的长度;计算字符出现的次数:用总长度减去子字符串长度。

oracle数据库服务器硬件配置要求 oracle数据库服务器硬件配置要求 May 10, 2024 am 04:00 AM

Oracle 数据库服务器硬件配置要求:处理器:多核,主频至少 2.5 GHz,大型数据库建议 32 核以上。内存:小型数据库至少 8GB,中等规模 16-64GB,大型数据库或高负载工作负载高达 512GB 或更多。存储:SSD 或 NVMe 磁盘,RAID 阵列提高冗余和性能。网络:高速网络(10GbE 或更高),专用网卡,低延迟网络。其他:稳定电源、冗余组件、兼容操作系统和软件、散热和冷却系统。

oracle需要多少内存 oracle需要多少内存 May 10, 2024 am 04:12 AM

Oracle 所需内存量取决于数据库大小、活动水平和所需性能水平:用于存储数据缓冲区、索引缓冲区、执行 SQL 语句和管理数据字典缓存。具体数量受数据库大小、活动水平和所需性能水平影响。最佳实践包括设置适当的 SGA 大小、调整 SGA 组件大小、使用 AMM 和监控内存使用情况。

oracle中替换字符串的方法 oracle中替换字符串的方法 May 08, 2024 pm 07:24 PM

Oracle 中替换字符串的方法是使用 REPLACE 函数,该函数的语法为:REPLACE(string, search_string, replace_string)。使用步骤:1. 识别要替换的子字符串;2. 确定替换子字符串的新字符串;3. 使用 REPLACE 函数进行替换。高级用法包括:多个替换、大小写敏感、特殊字符替换等。

See all articles