做房产网站,已经有了小区模板表,将小区的名称一律输入数据表中供登记用户进行选择。发现一个排序的问题:小区名称加载至下拉列表中时默认只是按照主键进行了升序排序,无任何规律,名称找起来非常麻烦。如何按小区名称第一个汉字的首字母进行排序?可原小区模版中并无拼音首字母字段。改数据表是不可行的,有几个系统都在使用此表,改动量巨大。于是决定从排序规则入手,参考有关资料进行解决。

Article address:http://blog.csdn.net/xuchangwei/

Author:XuChangwei

排序规则简介
什么叫排序规则呢? ms 是这样描述的: " 在 microsoft sql server 2000 中,字符串的物理存储由排序规则控制。排序规则指定表示每个字符的位模式以及存储和比较字符所使用的规则。 "
  在查询分析器内执行下面语句,可以得到 sql   server 支持的所有排序规则。
     select * from ::fn_helpcollations()
排序规则名称由两部份构成,前半部份是指本排序规则所支持的字符集。如:
   chinese_prc_cs_ai_ws
前半部份:指 unicode 字符集, chinese_prc_ 指针对大陆简体字 unicode 的排序规则。
排序规则的后半部份即后缀含义:
   _bin 二进制排序
   _ci(cs) 是否区分大小写, ci 不区分, cs 区分
   _ai(as) 是否区分重音, ai 不区分, as 区分   
   _ki(ks) 是否区分假名类型 ,ki 不区分, ks 区分 
     _wi(ws) 是否区分宽度 wi 不区分, ws 区分 

区分大小写 : 如果想让比较将大写字母和小写字母视为不等,请选择该选项。
区分重音 : 如果想让比较将重音和非重音字母视为不等,请选择该选项。如果选择该选项,比较还将重音不同的字母视为不等。
区分假名 : 如果想让比较将片假名和平假名日语音节视为不等,请选择该选项。
区分宽度 : 如果想让比较将半角字符和全角字符视为不等,请选择该选项
 
排序规则的应用
   sql server 提供了大量的 windows 和 sqlserver 专用的排序规则,但它的应用往往
被开发人员所忽略。其实它在实践中大有用处。
  例 1: 让表 name 列的内容按拼音排序:
create table #t(id int,name varchar(20))
insert #t select 1, 中
union all select 2, 国
union all select 3, 人
union all select 4, 阿


select * from #t order by name collate chinese_prc_cs_as_ks_ws
drop table #t
/* 结果:
id          name                
----------- --------------------
4           阿
2           国
3           人
1           中
*/
  例 2 :让表 name 列的内容按姓氏笔划排序:
create table #t(id int,name varchar(20))
insert #t select 1, 三
union all select 2, 乙
union all select 3, 二
union all select 4, 一
union all select 5, 十
select * from #t order by name collate chinese_prc_stroke_cs_as_ks_ws 
drop table #t
/* 结果:
id          name                
----------- --------------------
4           一
2           乙
3           二
5           十
1           三
*/

在实践中排序规则应用的扩展
   sql server 汉字排序规则可以按拼音、笔划等排序,那么我们如何利用这种功能
来处理汉字的一些难题呢?我现在举个例子:
          用排序规则的特性计算汉字笔划
  要计算汉字笔划,我们得先做准备工作,我们知道, windows 多国汉字, unicode 目前
收录汉字共 20902 个。简体 gbk 码汉字 unicode 值从 19968 开始。
  首先,我们先用 sqlserver 方法得到所有汉字,不用字典,我们简单利用 sql 语句就
可以得到:
select top 20902 code=identity(int,19968,1) into #t from syscolumns a,syscolumns b
再用以下语句,我们就得到所有汉字,它是按 unicode 值排序的:
   select code,nchar(code) as cnword from #t
  然后,我们用 select 语句,让它按笔划排序。
select code,nchar(code) as cnword
from #t
order by nchar(code) collate chinese_prc_stroke_cs_as_ks_ws,code

结果:
code        cnword
----------- ------
19968       一
20008       丨
20022       丶
20031       丿
20032       乀
20033       乁
20057       乙
20058       乚
20059       乛
20101       亅
19969       丁
..........

   从上面的结果,我们可以清楚的看到,一笔的汉字, code 是从 19968 到 20101 ,从小到大排,但到了二笔汉字的第一个字 “ 丁 ” , code 为 19969 ,就不按顺序而重新开始了。有了这结果,我们就可以轻松的用 sql 语句得到每种笔划汉字归类的第一个或最后一个汉字。下面用语句得到最后一个汉字:

create table #t1(id int identity,code int,cnword nvarchar(2))

insert #t1(code,cnword)
select code,nchar(code) as cnword  from #t
order by nchar(code) collate chinese_prc_stroke_cs_as_ks_ws,code


select a.cnword
from #t1 a
left join #t1 b on a.id=b.id-1 and a.code<b.code
where b.code is null
order by a.id

得到 36 个汉字,每个汉字都是每种笔划数按 chinese_prc_stroke_cs_as_ks_ws 排序规则排序后的
最后一个汉字:

亅阝马风龙齐龟齿鸩龀龛龂龆龈龊龍龠龎龐龑龡龢龝齹龣龥齈龞麷鸞麣龖龗齾齉龘

  上面可以看出: “ 亅 ” 是所有一笔汉字排序后的最后一个字, “ 阝 ” 是所有二笔汉字排序后的最后
一个字 ...... 等等。
  但同时也发现,从第 33 个汉字 “ 龗 (33 笔 )” 后面的笔划有些乱,不正确。但没关系,比 “ 龗 ” 笔划
多的只有四个汉字,我们手工加上:齾 35 笔,齉 36 笔,靐 39 笔,龘 64 笔

建汉字笔划表( tab_hzbh ):
create table tab_hzbh(id int identity,cnword nchar(1))
-- 先插入前 33 个汉字
insert tab_hzbh
select top 33 a.cnword
from #t1 a
left join #t1 b on a.id=b.id-1 and a.code<b.code
where b.code is null
order by a.id
-- 再加最后四个汉字
set identity_insert tab_hzbh on
go
insert tab_hzbh(id,cnword)
      select 35,n 齾
union all select 36,n 齉
union all select 39,n 靐
union all select 64,n 龘
go
set identity_insert tab_hzbh off
go

  到此为止,我们可以得到结果了,比如我们想得到汉字 “ 国 ” 的笔划:

declare @a nchar(1)
set @a= 国
select top 1 id
from  tab_hzbh
where cnword>=@a collate chinese_prc_stroke_cs_as_ks_ws
order by id

id         
-----------
8
( 结果:汉字 “ 国 ” 笔划数为 8)
  上面所有准备过程,只是为了写下面这个函数,这个函数撇开上面建的所有临时表和固
定表,为了通用和代码转移方便,把表 tab_hzbh 的内容写在语句内,然后计算用户输入一串
汉字的总笔划:

create function fun_getbh(@str nvarchar(4000))
returns int
as
begin
declare @word nchar(1),@n int
set @n=0
while len(@str)>0
begin
set @word=left(@str,1)
-- 如果非汉字,笔划当 0 计
set @n=@n+(case when unicode(@word) between 19968 and 19968+20901
then (select top 1 id from (
select 1 as id,n 亅 as word
union all select 2,n 阝
union all select 3,n 马
union all select 4,n 风
union all select 5,n 龙
union all select 6,n 齐
union all select 7,n 龟
union all select 8,n 齿
union all select 9,n 鸩
union all select 10,n 龀
union all select 11,n 龛
union all select 12,n 龂
union all select 13,n 龆
union all select 14,n 龈
union all select 15,n 龊
union all select 16,n 龍
union all select 17,n 龠
union all select 18,n 龎
union all select 19,n 龐
union all select 20,n 龑
union all select 21,n 龡
union all select 22,n 龢
union all select 23,n 龝
union all select 24,n 齹
union all select 25,n 龣
union all select 26,n 龥
union all select 27,n 齈
union all select 28,n 龞
union all select 29,n 麷
union all select 30,n 鸞
union all select 31,n 麣
union all select 32,n 龖
union all select 33,n 龗
union all select 35,n 齾
union all select 36,n 齉
union all select 39,n 靐
union all select 64,n 龘
) t
where word>=@word collate chinese_prc_stroke_cs_as_ks_ws
order by id asc) else 0 end)
set @str=right(@str,len(@str)-1)
end
return @n
end

-- 函数调用实例:
select dbo.fun_getbh( 中华人民共和国 ),dbo.fun_getbh( 中華人民共和國 )
 
  执行结果:笔划总数分别为 39 和 46 ,简繁体都行。

当然,你也可以把上面 “union   all” 内的汉字和笔划改存在固定表内,在汉字
列建 clustered index ,列排序规则设定为:
    chinese_prc_stroke_cs_as_ks_ws
这样速度更快。如果你用的是 big5 码的操作系统,你得另外生成汉字,方法一样。
但有一点要记住:这些汉字是通过 sql 语句 select 出来的,不是手工输入的,更不
是查字典得来的,因为新华字典毕竟不同于 unicode 字符集,查字典的结果会不正
确。

用排序规则的特性得到汉字拼音首字母

  用得到笔划总数相同的方法,我们也可以写出求汉字拼音首字母的函数。如下:

create function fun_getpy(@str nvarchar(4000))
returns nvarchar(4000)
as
begin
declare @word nchar(1),@py nvarchar(4000)
set @py=
while len(@str)>0
begin
set @word=left(@str,1)
-- 如果非汉字字符,返回原字符
set @py=@py+(case when unicode(@word) between 19968 and 19968+20901
then (select top 1 py from (
select a as py,n 驁 as word
union all select b,n 簿
union all select c,n 錯
union all select d,n 鵽
union all select e,n 樲
union all select f,n 鰒
union all select g,n 腂
union all select h,n 夻
union all select j,n 攈
union all select k,n 穒
union all select l,n 鱳
union all select m,n 旀
union all select n,n 桛
union all select o,n 漚
union all select p,n 曝
union all select q,n 囕
union all select r,n 鶸
union all select s,n 蜶
union all select t,n 籜
union all select w,n 鶩
union all select x,n 鑂
union all select y,n 韻
union all select z,n 咗
) t
where word>=@word collate chinese_prc_cs_as_ks_ws
order by py asc) else @word end)
set @str=right(@str,len(@str)-1)
end
return @py
end

-- 函数调用实例:
select dbo.fun_getpy( 中华人民共和国 ),dbo.fun_getpy( 中華人民共和國 )
结果都为: zhrmghg

   也可用相同的方法,扩展为得到汉字全拼的函数,甚至还可以得到全拼的读音声调,不过全拼分类大多了。得到全拼最好是用对照表,两万多汉字搜索速度很快,用对照表还可以充分利用表的索引。

SQL Server根据汉字笔划和取得拼音首字母进行排序相关推荐

  1. oracle中fn_getpy函数,SQL Server根据汉字笔划和取得拼音首字母进行排序

    select a.cnword from #t1 a left join #t1 b on a.id=b.id-1 and a.code where b.code is null order by a ...

  2. 用排序规则特点计算汉字笔划和取得拼音首字母

    SQL SERVER的排序规则平时使用不是很多,也许不少初学者还比较陌生,但有     一个错误大家应是经常碰到:   SQL   SERVER数据库,在跨库多表连接查询时,若两数据     库默认字 ...

  3. php 汉字按字母排序,在PHP中,将一个汉字数组按照拼音首字母进行排序

    (之前发的这篇博文因为含有敏感关键字,只好重发一遍了) $str = "我们可以在浏览器中看到,当鼠标移到元素上时,元素开始向右移动,开始比较慢,之后则比较快,移开时按原曲线回到原点.&qu ...

  4. PHP利用ICU扩展intl快速实现汉字转拼音以及按拼音首字母分组排序

    ICU(International Components for Unicode)里提供了transliterator(直译器), 可以很方便把其他语言(比如简体中文)转为拉丁文表示: http:// ...

  5. Java 输入汉字姓名 输出 姓名拼音 首字母缩写组合

    这几天想做一个这样子的功能:在查询客户信息的时候,可以直接根据客户姓名的拼音缩写进行,例如,输入 HZ 就可以查询到姓名为 [黄镇]的客户. 在网上查询到的比较好的做法是在客户信息字段中加上一个拼音缩 ...

  6. java取拼音首字母_java怎么根据汉字获取字的拼音首字母

    展开全部 这里可以使用62616964757a686964616fe58685e5aeb931333363393633 pinyin4. jar包来进行转化,pinyin4. jar可以自行在网上进行 ...

  7. Java实现根据拼音首字母的排序

    1.项目 手机APP端要对企业列表按企业名称首字母(如果企业名是英文的就按)进行分类排序,效果如下: 2.实现过程 2.1 首先引入项目的pinyin4j-2.5.0.jar包. 这个jar的下载地址 ...

  8. php实现通讯录按字母分组,iOS - 通讯录开发,名字按拼音首字母分组排序

    应项目需要,需添加一个自定义的通讯录,所以需要对联系人按名字的首字母进行排序.以下方法已经封装好,复制到项目中直接可以使用. 该方法是使用UILocalizedIndexedCollation来进行本 ...

  9. 通讯录c语言编程按字母分组,iOS - 通讯录开发,名字按拼音首字母分组排序

    应项目需要,需添加一个自定义的通讯录,所以需要对联系人按名字的首字母进行排序.以下方法已经封装好,复制到项目中直接可以使用. 该方法是使用UILocalizedIndexedCollation来进行本 ...

最新文章

  1. 《深入理解ElasticSearch》——2.4 批量操作
  2. Merkle山脉(Merkle Mountain Range)详解
  3. Intel Realsense D435 pyrealsense2 get_option_description() rs.option中获取参数描述
  4. Java Swing井字游戏
  5. MATLAB 图形着色
  6. 图片在section上下居中_新媒体运营者关于图片使用的几大要点
  7. 敏捷开发:影响地图工作坊的反思
  8. java三元运算符与类型强制转换
  9. win10系统QQ音乐安装包无法打开解决方法!
  10. Blake2b算法 php,Blake2b算法是什么?Blake2b算法币种盘点
  11. wp网站,wordpress网站搭建,wp网站建设教程
  12. [转贴]杨式太极拳八十五式通释—2—王志远
  13. HANA 存储过程 YTD
  14. 服务端渲染和客户端渲染
  15. 交通仿真软件国内外详情分析及发展概述
  16. Azuki:缔造NFT元宇宙品牌
  17. 赠书丨如何高效学习计算机视觉?
  18. KubeEdge环境搭建(支持网络插件flannel)
  19. hMailServer 使用教程 —— 手把手教你搭建自己的邮箱服务器
  20. python:talib 计算 KDJ 用 pro_api

热门文章

  1. n级lfsr输出m序列c语言,第2章流密码(LFSR)
  2. poj1088 滑雪 记忆化搜索
  3. linux学习路线-韦东山:史上最全嵌入式Linux学习路线图
  4. vc技术内幕第六版_六个月内幕-我还邪恶吗?
  5. PWA 实践/应用(Google Workbox)
  6. Java快速创建多级目录
  7. CentOS6与CentOS7的差异对比
  8. javaweb实现停车场收费管理系统
  9. 解决hexo下分类和标签无法显示的问题
  10. 02 | 领域、子域、核心域、通用域和支撑域:傻傻分不清?