专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »数据库 » sql语句实例讲解:讲解SQL 2000的Collection排序规则 »正文

sql语句实例讲解:讲解SQL 2000的Collection排序规则

来源: 发布时间:星期日, 2009年8月16日 浏览:0次 评论:0
  SQL Server排序规则很多人使用并不是很多对于初学者来讲会感觉特别陌生但其中有很多人都是经常碰到: SQL Server数据库在跨库多表连接查询时若两数据库默认集区别系统就会返回这样:

  “无法解决 equal to 操作排序规则冲突

  分析:

  这个排序规则不致造成测试如下:


  create table #t1(
  name varchar(20) collate Albanian_CI_AI_WS,
  value )
  create table #t2(
  name varchar(20) collate Chinese_PRC_CI_AI_WS,
  value )


  表建好后再来执行连接查询:


  select * from #t1 A inner join #t2 B _disibledevent=>

  此时就出现了:

  服务器: 消息 446级别 16状态 9行 1

  无法解决 equal to 操作排序规则冲突

  要排除这个最简单思路方法是表连接时指定它排序规则这样就不再出现了语句这样写:


  select *
  from #t1 A inner join #t2 B
  on A.name=B.name collate Chinese_PRC_CI_AI_WS


   2.排序规则介绍:

  什么叫排序规则呢?MS是这样描述:"在 Microsoft SQL Server 2000 中物理存储由排序规则控制排序规则指定表示每个位模式以及存储和比较所使用规则"在查询分析器内执行下面语句可以得到SQL SERVER支持所有排序规则


  select * from ::fn_helpcollations


  排序规则名称由两部份构成前半部份是指本排序规则所支持如:


  Chinese_PRC_CS_AI_WS

  前半部份:指UNICODEChinese_PRC_指针对大陆简体字UNICODE排序规则

  排序规则后半部份即后缀 含义:

  _BIN 2进制排序

  _CI(CS) 是否区分大小写CI不区分CS区分

  _AI(AS) 是否区分重音AI不区分AS区分

  _KI(KS) 是否区分假名类型,KI不区分KS区分

  _WI(WS) 是否区分宽度 WI不区分WS区分

  区分大小写:如果想让比较将大写字母和小写字母视为不等请选择该选项

  区分重音:如果想让比较将重音和非重音字母视为不等请选择该选项如果选择该选项

  比较还将重音区别字母视为不等

  区分假名:如果想让比较将片假名和平假名日语音节视为不等请选择该选项

  区分宽度:如果想让比较将半角和全角视为不等请选择该选项

   3.排序规则应用:

  SQL Server提供了大量Windows和SQLSERVER专用排序规则但它应用往往被开发人员所忽略其实它在实战中大有用处

  例1:让表NAME列内容按拼音排序:


  create table #t(id ,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 ,name varchar(20))
  insert #t select 1,' 3'
  union all select 2,'乙'
  union all select 3,' 2'
  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 2
  5 十
  1 3
  */


   4.在实战中排序规则应用扩展

  SQL Server汉字排序规则可以按拼音、笔划等排序那么我们如何利用这种功能来处理汉字些难题呢?我现在举个例子: 用排序规则特性计算汉字笔划

  要计算汉字笔划我们得先做准备工作我们知道Windows多国汉字UNICODE目前收录汉字共20902个简体GBK码汉字UNICODE值从19968开始

  首先我们先用SQLSERVER思路方法得到所有汉字不用字典我们简单利用SQL语句就可以得到:


  select top 20902 code=identity(,19968,1) o #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从小到大排但到了 2笔汉字个字“丁”CODE为19969就不按顺序而重新开始了有了这结果我们就可以轻松用SQL语句得到每种笔划汉字归类个或最后个汉字

  下面用语句得到最后个汉字:


  create table #t1(id identity,code ,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 _disibledevent=>  where B.code is null
  order by A.id


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

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

  上面可以看出:“亅”是所有笔汉字排序后最后个字“阝”是所有 2笔汉字排序后最后个字......等等

  但同时也发现从第33个汉字“龗(33笔)”后面笔划有些乱不正确但没关系比“龗”笔划多只有 4个汉字我们手工加上:齾35笔齉36笔靐39笔龘64笔

  建汉字笔划表(TAB_HZBH):


  create table tab_hzbh(id identity,cnword nchar(1))

  --先插入前33个汉字


  insert tab_hzbh
  select top 33 A.cnword
  from #t1 A
  left join #t1 B _disibledevent=>  where B.code is null
  order by A.id


  --再加最后 4个汉字


   identity_insert tab_hzbh _disibledevent=>  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))
  s
  as
  begin
  declare @word nchar(1),@n
   @n=0
  while len(@str)>0
  begin
   @word=left(@str,1)

  --如果非汉字笔划当0计


   @n=@n+( 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) 0 end)
   @str=right(@str,len(@str)-1)
  end
   @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))
  s nvarchar(4000)
  as
  begin
  declare @word nchar(1),@PY nvarchar(4000)
   @PY=''
  while len(@str)>0
  begin
   @word=left(@str,1)


  --如果非汉字返回原


   @PY=@PY+( 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) @word end)
   @str=right(@str,len(@str)-1)
  end
   @PY
  end


  例子:


  select dbo.fun_getPY('中华人民共和国'),dbo.fun_getPY('中華人民共和國')


  结果都是:ZHRMGHG

  大家如果有兴趣可以使用相同思路方法扩展得到汉字全拼甚至你还可以得到全拼读音声调不过全拼分类大多了得到全拼最好还是用对照表两万多汉字搜索速度显然很快另外用对照表还可以充分利用表索引
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: