oracle 使用order by 对汉字进行多字段排序
今天遇到一个奇怪的问题, 在两个不同的数据库里执行同样的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函数在国际化支持上提供了一个非常好的排序解决方案。在具体应用环境下有其重要的意义。善用之。

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

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

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

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

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

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

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

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

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