sql server 2019 无法用 collate 直接提取拼音首字母,chinese_prc_cs_as 仅按 unicode 码点排序,非真实拼音;最稳妥方案是建汉字→首字母映射表并用 chinese_prc_cs_as 定义列排序规则。

SQL Server 2019 无法直接用 COLLATE 提取拼音首字母,必须借助映射表或 CLR 函数;临时用 Chinese_PRC_CS_AS 排序只是按 Unicode 码点“伪拼音”,不是真正首字母分组。
为什么 Chinese_PRC_CS_AS 不等于拼音首字母排序
这个排序规则确实能让中文“大致按读音归组”,但底层是按汉字 Unicode 码点顺序排的。比如 “吖”(U+5416)、“罢”(U+7F62)、“嚓”(U+563B)——它们的码点不对应 A/B/C,而是杂乱分布。执行 ORDER BY name COLLATE Chinese_PRC_CS_AS 后,“阿”“八”“春”看似有序,实则是巧合;一旦混入“赵”“孙”“李”,顺序就不可控。它不生成字母,也不支持 SUBSTRING() 或 LEFT() 提取首字母。
最稳妥:建一张汉字→首字母映射表
这是生产环境最常用、最可控的方式,兼容所有 SQL Server 版本(包括 2019),且性能可接受(加索引后 JOIN 很快)。
- 建表语句示例:
CREATE TABLE chinese_initial_map ( hanzi CHAR(1) COLLATE Chinese_PRC_CS_AS PRIMARY KEY, initial CHAR(1) NOT NULL ); - 插入常见姓氏/首字(覆盖约 3500 字即可应付 99% 场景),例如:
INSERT INTO chinese_initial_map VALUES ('阿','A'),('八','B'),('陈','C'),('丁','D'),('冯','F'),('郭','G'),('何','H'),('蒋','J'),('孔','K'),('李','L'),('马','M'),('牛','N'),('欧','O'),('彭','P'),('齐','Q'),('任','R'),('沈','S'),('唐','T'),('万','W'),('项','X'),('杨','Y'),('赵','Z'); - 查询时 JOIN 使用:
SELECT t.* FROM users t LEFT JOIN chinese_initial_map m ON LEFT(t.name, 1) = m.hanzi ORDER BY ISNULL(m.initial, 'Z'), t.name;
注意用ISNULL(m.initial, 'Z')把未映射字兜底到末尾
想省事但要承担风险:用 UNICODE() + 查表硬编码
如果只排姓名且数据量小、汉字极有限(如内部系统只有几十个固定名字),可不用建表,改用 CASE WHEN 手动映射:
SELECT *,
CASE LEFT(name, 1)
WHEN N'李' THEN 'L'
WHEN N'王' THEN 'W'
WHEN N'张' THEN 'Z'
WHEN N'刘' THEN 'L'
ELSE 'X'
END AS initial
FROM users
ORDER BY initial, name;
但要注意:
- 每个汉字都要写一行,维护成本高,3500 字就得 3500 行
WHEN -
N'李'必须加N前缀,否则可能因隐式转换丢失字符 - 无法处理多音字(如“重”可读 chóng / zhòng),得按业务约定选一个
CLR 方案可行但通常被禁用
SQL Server 支持用 C# 写函数调用第三方拼音库(如 PinYinConverter),性能好、准确率高。但实际落地有硬门槛:
- 需 DBA 开启
TRUSTWORTHY ON或对程序集签名,多数生产环境策略禁止 - 需要额外部署 DLL,升级/迁移时容易遗漏
- 2019 默认禁用
sp_configure 'show advanced options',开启步骤繁琐 - 函数内若调用非安全 API(如网络、文件),会被 SQL Server 拒绝加载
除非你完全掌控数据库权限且有长期维护人力,否则别碰。
真正容易被忽略的是:**映射表必须用 Chinese_PRC_CS_AS 定义 hanzi 列的排序规则,否则 JOIN 时大小写或重音敏感性会导致匹配失败**。另外,如果 name 字段含空格或标点(如“张-伟”),LEFT(name, 1) 取到的就不是汉字——得先 TRIM() 或正则清洗,这点常被跳过。










