大家好!我是只谈技术不剪发的 Tony 老师。

在创建数据库或者表时,我们需要指定一个字符集(Charset)和排序规则(Collation)。

字符集决定了数据库能够存储哪些字符,比如 ASCII 字符集只能存储简单的英文、数字和一些控制字符;GB2312 字符集可以存储中文;Unicode 字符集能够支持世界上的各种语言。

排序规则定义了字符集中字符的排序顺序,包括是否区分大小写,是否区分重音等。对于中文而言,排序方式与英文有所不同;中文通常需要按照拼音、偏旁部首或者笔画进行排序。

如果想要支持中文排序,最简单的方式就是使用支持中文排序的字符集和排序规则;但是常见的 Unicode 字符集默认不支持中文排序。所以我们需要解决这种情况下的中文排序问题。

Oracle

Oracle 中支持汉字排序的字符集包括 ZHS16GBK 等。如果使用 AL32UTF8 字符编码则不支持中文排序规则,我们可以通过一个转换函数实现该功能。以下示例按照员工姓名的拼音进行排序(示例表和数据点此下载):

-- Oracle 实现中文拼音排序
SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY NLSSORT(emp_name,'NLS_SORT = SCHINESE_PINYIN_M');

NLSSORT 是一个 Oracle 系统函数,返回了按照某种排序规则得到的字符序列;SCHINESE_PINYIN_M 表示中文的拼音排序规则。该查询的结果如下:

EMP_NAME|
--------+
关平     |
关兴     |
廖化     |
马岱     |
张苞     |
赵氏     |
赵统     |
赵云     |
周仓     |

除了按照拼音排序之外,Oracle 还支持按照偏旁部首(SCHINESE_RADICAL_M)以及笔画(SCHINESE_STROKE_M)进行中文排序。

MySQL

MySQL 支持中文排序的字符集包括 GBK 等。如果使用默认的 utf8mb4 字符编码,中文按照偏旁部首进行排序。我们可以通过一个转换函数实现其他方式的中文排序,以下查询按照员工姓名的拼音进行排序:

-- MySQL实现中文拼音排序
SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY CONVERT(emp_name USING GBK);

其中,CONVERT 是一个 MySQL 系统函数,用于转换数据的字符集编码,中文 GBK 字符集默认使用拼音进行排序。查询返回的结果和上面的 Oracle 示例相同。

Microsoft SQL Server

Microsoft SQL Server 中的字符集和排序规则是同一个概念,安装数据库时默认根据操作系统所在的区域进行设置,中国地区默认使用 Chinese_PRC_CI_AS 排序规则,对于中文按照偏旁部首进行排序。

我们可以通过 COLLATE 关键字实现其他方式的中文排序,以下查询按照员工姓名的拼音进行排序:

-- Microsoft SQL Server 实现中文拼音排序
SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY emp_name COLLATE Chinese_PRC_CI_AI_KS_WS;

其中,COLLATE 表示按照某种排序规则进行排序,Chinese_PRC_CI_AI_KS_WS 表示中文拼音排序规则。查询返回的结果和上面的 Oracle 示例一样。

另外,Microsoft SQL Server 也支持中文按照笔画进行排序(Chinese_PRC_Stroke_CI_AS)。

PostgreSQL

PostgreSQL 推荐使用 UTF8 编码字符集,中文按照偏旁部首进行排序。我们可以通过 COLLATE 关键字实现其他方式的中文排序,以下查询按照员工姓名的拼音进行排序:

-- PostgreSQL 实现中文拼音排序
SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY emp_name COLLATE "zh_CN";

其中,COLLATE 表示按照某种排序规则进行排序,zh_CN 表示中文拼音排序规则。查询返回的结果和上面的 Oracle 示例一样。

另外,我们也可以使用 CONVERT_TO 函数讲汉字从 UTF8 编码转换为 GBK 编码后按照拼音进行排序:

SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY CONVERT_TO(emp_name,'gbk');

SQLite

SQLite 默认使用 UTF-8 字符编码,中文按照偏旁部首进行排序,不支持其他的排序方式。

SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY emp_name;emp_name|
--------+
关兴     |
关平     |
周仓     |
廖化     |
张苞     |
赵云     |
赵氏     |
赵统     |
马岱     |

自定义排序

除了使用字符集和排序规则定义的排序顺序之外,我们也可以通过 CASE 表达式为不同的汉字指定一个自定义的排序规则。例如:

SELECT emp_name
FROM employee
WHERE dept_id = 4
ORDER BY CASE WHEN emp_name LIKE '赵%' THEN 1WHEN emp_name LIKE '钱%' THEN 2WHEN emp_name LIKE '孙%' THEN 3WHEN emp_name LIKE '李%' THEN 4...ELSE 999END;

我们可以继续扩展以上 CASE 表达式,实现按照百家姓的姓氏顺序排列。

为了避免每次都需要编写一个很长的 CASE 表达式,我们也可以创建一个百家姓表:

CREATE TABLE names(id INT PRIMARY KEY, last_name VARCHAR(20));
INSERT INTO names VALUES (1, '赵');
INSERT INTO names VALUES (2, '钱');
INSERT INTO names VALUES (3, '孙');
INSERT INTO names VALUES (4, '李');
...

然后再通过连接查询实现自定义的排序规则,例如:

SELECT e.emp_name
FROM employee e
LEFT JOIN names n ON e.emp_name LIKE concat(n.last_name,'%')
WHERE dept_id = 4
ORDER BY n.id;

总结

本文总结了在数据库中实现中文汉字排序的几种方法:

  • 使用支持中文排序的字符集和排序规则;
  • 在查询语句中使用函数将中文转换为特点的字符集和排序规则;
  • 使用 CASE 表达式或者自定义的字典表实现中文排序。

如果你觉得文章有用,欢迎评论

数据库实现中文汉字排序终极指南相关推荐

  1. Java8对中文汉字排序的Comparator实现类

    最近由于工作需要需要对中文汉字排序,编写了Comparator实现类分享给大家. 直接上代码: import java.util.Comparator;public class ChineseComp ...

  2. Java数组中文排序_Java模块 -- 数组/集合中文汉字排序(支持生僻汉字)

    这里举例List集合 , 对list中的中文进行排序 , 按照中文拼音首字母. 支持生僻汉字的话 , 需要使用一个jar包 , 链接地址如下 传统的 : List list = new ArrayLi ...

  3. Java中文汉字排序

    概述 我们在应用程序中可能会经常遇到对中文排序的问题,例如姓名列表,词汇表等等.对中文排序,我们使用比较多的是根据汉语拼音发音来确定顺序. 我们可能会经常使用 java.util.Set接口, jav ...

  4. MySQL根据中文汉字排序查询

    在MySQL中当说到进行排序查询时,大家的第一反应就是使用 ORDER BY 方法指定列进行排序,但是如果要指定列为中文数据按照首字母排序时,就会发现 ORDER BY 方法排序的顺序其实是有问题的. ...

  5. oracle数据库按中文拼音排序

    Oracle9i 新增了按照拼音.部首.笔画排序功能,在使用时一般都是按拼音排序, 按照拼音排序: select * from [表名]order by nlssort([栏位名],'NLS_SORT ...

  6. mysql按中文汉字排序

    SELECT * FROM [表名] order by CONVERT([字段] USING gbk) https://blog.csdn.net/jay168999/article/details/ ...

  7. Collections.sort实现倒序汉字拼音排序,默认是按照正序进行汉字拼音排序MYSQL语句支持汉字排序SQL汉字排序

    前言: 需求上遇到过,业务希望一些下拉框,按照汉字拼音的顺序来进行展示,需要对下拉框的List进行排序. 特别注意: Collections.reverse()方法是将数据倒置,并非倒序直接排序. 倒 ...

  8. oracle数据库的字段怎么排序规则,Oracle中文、数字混杂字段的排序

    对Oracle中中文.数字混杂形式的字段进行排序的方法: 例如: orderbyNLSSORT(字段名,'NLS_SORT = SCHINESE_PINYIN_M'), to_number(trans ...

  9. oracle中文的升序降序,Oracle汉字排序

    Oracle汉字排序 使用一下SQL select * from T_0303003 order by stock_holder 进行选取数据时(stock_holder为存放中文的字段),结果发现两 ...

  10. Java字母笔顺_Android实现中文汉字笔划(笔画)、中文拼音排序、英文排序

    一.需求描述 最近要做一个类似微信的,在登录界面选择国家地区的功能,微信有中文汉字笔画排序以及中文拼音排序等几种方式,如下所示: 微信:简体中文.拼音排序 微信:繁体中文.笔画排序 微信 英文 字母排 ...

最新文章

  1. 携程python_Python 携程
  2. 强化学习圣经:《强化学习导论》第二版(附PDF下载)
  3. python 多线程 多进程 zmq_研二硕, Python +pyqt,多进程问题求助
  4. abstract interface 和 interface 没有区别
  5. Linq使用Group By
  6. ubuntu ???????????? no permissions 问题解决
  7. linux多进程通过中断实现,Linux驱动中断上下文中会发生什么结果实验测试
  8. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 4丨员工薪水中位数【难度困难】
  9. 大咖面对面 | 陈果果博士谈智能语音
  10. 关于CSS中定位的个人理解
  11. 多模块Struts应用程序的几个问题(及部分解决方法)
  12. linux 命令行删除分区,如何在 Linux 中删除分区
  13. 外部表不是预期的格式 解决方案
  14. presentModalViewController和dismissModalViewControllerAnimated的使用总结
  15. 现代汉语词典第五版_瑜 典 寻 瑕——第五版《现代汉语词典》的瑕疵(周克庸原创)...
  16. YYH的营救计划(NOIP模拟赛Round 6)
  17. Gitea:从SVN迁移到Git
  18. 使用mysqldump+WinRAR压缩备份数据库
  19. windows 8 Surface 会成功吗?
  20. ResultSet(结果集)、Statement

热门文章

  1. win10系统字体颜色变淡
  2. 从目标文件结构,加载、执行阶段,汇编角度来理解C程序内存分区
  3. 关了浏览器再开,怎么session还在?
  4. 刘意-java基础视频(API-网络编程)笔记
  5. JAVA代码编译流程
  6. 视频教程-WPF MVVM 编程模式/框架 基础+提高 项目开发实战视频教程-.NET
  7. 2020华为软挑总结
  8. SENT协议学习总结
  9. Proteus 8 Professional 下载安装教程
  10. AnimMontage(中文翻译)——UE4官方文档