仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 653|回复: 8
打印 上一主题 下一主题

[学习教程] MYSQL网站制作之用排序划定规矩特性盘算汉字笔画和获得拼音...

[复制链接]
愤怒的大鸟 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:30:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
“MySQL实际上是一个数据库家族,你可以从选择一个并将其配置成可以满足你的大多数情况,”开源顾问公司Ethiqa的总裁如此表示,“因此,你可以在开始的时候选择一个小巧的版本产品,以后再根据需要来对其进行性能或大小上的扩展。”汉字|排序|拼音 SQL SERVER的排序划定规矩平常利用不是良多,大概很多初学者还对照生疏,但有
一个毛病人人应是常常碰着:SQLSERVER数据库,在跨库多表毗连查询时,若两数据
库默许字符集分歧,体系就会前往如许的毛病:

“没法办理equalto操纵的排序划定规矩抵触。”

一.毛病剖析:
  这个毛病是由于排序划定规矩纷歧致酿成的,我们做个测试,好比:
createtable#t1(
namevarchar(20)collateAlbanian_CI_AI_WS,
valueint)

createtable#t2(
namevarchar(20)collateChinese_PRC_CI_AI_WS,
valueint)

表建好后,实行毗连查询:

select*from#t1Ainnerjoin#t2BonA.name=B.name

如许,毛病就呈现了:

服务器:动静446,级别16,形态9,行1
没法办理equalto操纵的排序划定规矩抵触。
  要扫除这个毛病,最复杂办法是,表毗连时指定它的排序划定规矩,如许毛病就
不再呈现了。语句如许写:

select*
from#t1Ainnerjoin#t2B
onA.name=B.namecollateChinese_PRC_CI_AI_WS


二.排序划定规矩简介:

甚么叫排序划定规矩呢?MS是如许形貌的:"在MicrosoftSQLServer2000中,
字符串的物理存储由排序划定规矩把持。排序划定规矩指定暗示每一个字符的位形式和存
储和对照字符所利用的划定规矩。"
  在查询剖析器内实行上面语句,能够失掉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辨别 

辨别巨细写:假如想让对照将年夜写字母和小写字母视为不等,请选择该选项。
辨别重音:假如想让对照将重音和非重音字母视为不等,请选择该选项。假如选择该选项,
对照还将重音分歧的字母视为不等。
辨别化名:假如想让对照将片化名战争化名日语音节视为不等,请选择该选项。
辨别宽度:假如想让对照将半角字符和全角字符视为不等,请选择该选项


三.排序划定规矩的使用:
  SQLSERVER供应了大批的WINDOWS和SQLSERVER公用的排序划定规矩,但它的使用常常
被开辟职员所疏忽。实在它在理论中年夜有效处。

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

createtable#t(idint,namevarchar(20))
insert#tselect1,中
unionallselect2,国
unionallselect3,人
unionallselect4,阿

select*from#torderbynamecollateChinese_PRC_CS_AS_KS_WS
droptable#t
/*了局:
idname
-------------------------------
4阿
2国
3人
1中
*/

  例2:让表NAME列的内容按姓氏笔画排序:

createtable#t(idint,namevarchar(20))

insert#tselect1,三
unionallselect2,乙
unionallselect3,二
unionallselect4,一
unionallselect5,十
select*from#torderbynamecollateChinese_PRC_Stroke_CS_AS_KS_WS
droptable#t
/*了局:
idname
-------------------------------
4一
2乙
3二
5十
1三
*/

四.在理论中排序划定规矩使用的扩大
  SQLSERVER汉字排序划定规矩能够按拼音、笔画等排序,那末我们怎样使用这类功效
来处置汉字的一些困难呢?我如今举个例子:

          用排序划定规矩的特征盘算汉字笔画

  要盘算汉字笔画,我们得先做筹办事情,我们晓得,WINDOWS多国汉字,UNICODE今朝
收录汉字共20902个。简体GBK码汉字UNICODE值从19968入手下手。
  起首,我们先用SQLSERVER办法失掉一切汉字,不必字典,我们复杂使用SQL语句就
能够失掉:

selecttop20902code=identity(int,19968,1)into#tfromsyscolumnsa,syscolumnsb

再用以下语句,我们就失掉一切汉字,它是按UNICODE值排序的:

  selectcode,nchar(code)asCNWordfrom#t

  然后,我们用SELECT语句,让它按笔画排序。

selectcode,nchar(code)asCNWord
from#t
orderbynchar(code)collateChinese_PRC_Stroke_CS_AS_KS_WS,code

了局:
codeCNWord
-----------------
19968一
20008丨
20022丶
20031丿
20032T
20033U
20057乙
20058]
20059^
20101|
19969丁
..........

 从下面的了局,我们能够分明的看到,一笔的汉字,code是从19968到20101,从小到年夜排,但到
了二笔汉字的第一个字“丁”,CODE为19969,就不按按次而从头入手下手了。有了这了局,我们就能够轻
松的用SQL语句失掉每种笔画汉字回类的第一个或最初一个汉字。
上面用语句失掉最初一个汉字:

createtable#t1(idintidentity,codeint,cnwordnvarchar(2))

insert#t1(code,cnword)
selectcode,nchar(code)asCNWordfrom#t
orderbynchar(code)collateChinese_PRC_Stroke_CS_AS_KS_WS,code


selectA.cnword
from#t1A
leftjoin#t1BonA.id=B.id-1andA.code<B.code
whereB.codeisnull
orderbyA.id

失掉36个汉字,每一个汉字都是每种笔画数按Chinese_PRC_Stroke_CS_AS_KS_WS排序划定规矩排序后的
最初一个汉字:

|阝马风龙齐龟齿鸩龀龛龆龈龊龠PK[Q

  下面能够看出:“|”是一切一笔汉字排序后的最初一个字,“阝”是一切二笔汉字排序后的最初
一个字......等等。
  但同时也发明,从第33个汉字“(33笔)”前面的笔画有些乱,不准确。但不妨,比“”笔画
多的只要四个汉字,我们手工加上:35笔,Q36笔,h39笔,64笔

建汉字笔画表(TAB_HZBH):
createtabletab_hzbh(idintidentity,cnwordnchar(1))
--先拔出前33个汉字
inserttab_hzbh
selecttop33A.cnword
from#t1A
leftjoin#t1BonA.id=B.id-1andA.code<B.code
whereB.codeisnull
orderbyA.id
--再加最初四个汉字
setidentity_inserttab_hzbhon
go
inserttab_hzbh(id,cnword)
     select35,N
unionallselect36,NQ
unionallselect39,Nh
unionallselect64,N
go
setidentity_inserttab_hzbhoff
go

  到此为止,我们能够失掉了局了,好比我们想失掉汉字“国”的笔画:

declare@anchar(1)
set@a=国
selecttop1id
fromtab_hzbh
wherecnword>=@acollateChinese_PRC_Stroke_CS_AS_KS_WS
orderbyid

id
-----------
8
(了局:汉字“国”笔画数为8)

  下面一切筹办历程,只是为了写上面这个函数,这个函数撇开下面建的一切一时表和固
定表,为了通用和代码转移便利,把表tab_hzbh的内容写在语句内,然后盘算用户输出一串
汉字的总笔画:

createfunctionfun_getbh(@strnvarchar(4000))
returnsint
as
begin
declare@wordnchar(1),@nint
set@n=0
whilelen(@str)>0
begin
set@word=left(@str,1)
--假如非汉字,笔画当0计
set@n=@n+(casewhenunicode(@word)between19968and19968+20901
then(selecttop1idfrom(
select1asid,N|asword
unionallselect2,N阝
unionallselect3,N马
unionallselect4,N风
unionallselect5,N龙
unionallselect6,N齐
unionallselect7,N龟
unionallselect8,N齿
unionallselect9,N鸩
unionallselect10,N龀
unionallselect11,N龛
unionallselect12,N
unionallselect13,N龆
unionallselect14,N龈
unionallselect15,N龊
unionallselect16,N
unionallselect17,N龠
unionallselect18,N
unionallselect19,N
unionallselect20,N
unionallselect21,N
unionallselect22,N
unionallselect23,N
unionallselect24,N
unionallselect25,N
unionallselect26,N
unionallselect27,NP
unionallselect28,N
unionallselect29,NK
unionallselect30,N[
unionallselect31,N
unionallselect32,N
unionallselect33,N
unionallselect35,N
unionallselect36,NQ
unionallselect39,Nh
unionallselect64,N
)T
whereword>=@wordcollateChinese_PRC_Stroke_CS_AS_KS_WS
orderbyidASC)else0end)
set@str=right(@str,len(@str)-1)
end
return@n
end

--函数挪用实例:
selectdbo.fun_getbh(中华国民共和国),dbo.fun_getbh(中A国民共和)
 
  实行了局:笔画总数分离为39和46,简繁体都行。
――――――――――――――――――――――――――――――――――――――――固然,你也能够把下面“UNION ALL”内的汉字和笔画改存在流动表内,在汉字
列建CLUSTEREDINDEX,列排序划定规矩设定为:
   Chinese_PRC_Stroke_CS_AS_KS_WS
如许速率更快。假如你用的是BIG5码的操纵体系,你得别的天生汉字,办法一样。
但有一点要记着:这些汉字是经由过程SQL语句SELECT出来的,不是手工输出的,更不
是查字典得来的,由于新华字典究竟分歧于UNICODE字符集,查字典的了局会不正
确。

  
    用排序划定规矩的特征失掉汉字拼音首字母

  用失掉笔画总数不异的办法,我们也能够写出求汉字拼音首字母的函数。以下:

createfunctionfun_getPY(@strnvarchar(4000))
returnsnvarchar(4000)
as
begin
declare@wordnchar(1),@PYnvarchar(4000)
set@PY=
whilelen(@str)>0
begin
set@word=left(@str,1)
--假如非汉字字符,前往原字符
set@PY=@PY+(casewhenunicode(@word)between19968and19968+20901
then(selecttop1PYfrom(
selectAasPY,Nasword
unionallselectB,N簿
unionallselectC,Ne
unionallselectD,Nz
unionallselectE,N
unionallselectF,Nv
unionallselectG,NB
unionallselectH,N
unionallselectJ,Nh
unionallselectK,Ni
unionallselectL,Nw
unionallselectM,N
unionallselectN,N
unionallselectO,Na
unionallselectP,N曝
unionallselectQ,N
unionallselectR,NU
unionallselectS,NR
unionallselectT,NX
unionallselectW,NF
unionallselectX,NR
unionallselectY,N
unionallselectZ,N
)T
whereword>=@wordcollateChinese_PRC_CS_AS_KS_WS
orderbyPYASC)else@wordend)
set@str=right(@str,len(@str)-1)
end
return@PY
end

--函数挪用实例:
selectdbo.fun_getPY(中华国民共和国),dbo.fun_getPY(中A国民共和)
了局都为:ZHRMGHG

 你如有乐趣,也可用不异的办法,扩大为失掉汉字全拼的函数,乃至还能够失掉全拼的读
音腔调,不外全拼分类年夜多了。失掉全拼最好是用对比表,两万多汉字搜刮速率很快,用对比
表还能够充实使用表的索引。
排序划定规矩另有良多别的的奇妙用法,限于篇幅在此就不再具体申明。接待人人配合切磋。
――――――――――――――――――――――――――――――――――――
以下是用PL/SQL写的:



createorreplacefunctionfun_getPY(strvarchar2)
returnsvarchar2
as

wordchar(1);
PYvarchar2(4000):=;

begin
whilelength(str)>0loop
word:=lpad(str,1);
PY:=PY+(casewhenunicode(word)between19968and19968+20901
then(selectPYfrom(select*from(
selectAasPY,Nasword
unionallselectB,N簿
unionallselectC,Ne
unionallselectD,Nz
unionallselectE,N
unionallselectF,Nv
unionallselectG,NB
unionallselectH,N
unionallselectJ,Nh
unionallselectK,Ni
unionallselectL,Nw
unionallselectM,N
unionallselectN,N
unionallselectO,Na
unionallselectP,N曝
unionallselectQ,N
unionallselectR,NU
unionallselectS,NR
unionallselectT,NX
unionallselectW,NF
unionallselectX,NR
unionallselectY,N
unionallselectZ,N
)TorderbyPYASC)
whererownum<2andword>=wordcollateChinese_PRC_CS_AS_KS_WS
)elsewordend)
str:=rpad(str,length(str)-1);
endloop;
returnPY;
endfun_getPY;

MySQL已经为支持所有最流行的Web2.0语言做好了准备,诸如Ruby、Ajax等,当然还有PHP。有的业界分析师说过,“每一个Web2.0公司实质上就是一个数据库公司。
冷月葬花魂 该用户已被删除
沙发
发表于 2015-1-19 15:52:43 | 只看该作者
一个百万级别的基本信息表A,一个百万级别的详细记录表B,A中有个身份证id,B中也有身份id;先要找出A中在B的详细记录。
因胸联盟 该用户已被删除
板凳
发表于 2015-1-25 12:07:27 | 只看该作者
比如,MicrosoftSQLServer2008的某一个版本可以满足现在的这个业务的需要,而且价格还比Oracle11g要便宜,那么这一产品就是适合的。
乐观 该用户已被删除
地板
发表于 2015-2-2 22:02:35 来自手机 | 只看该作者
是要和操作系统进行Socket通讯的场景。否则建议慎重!
小女巫 该用户已被删除
5#
发表于 2015-2-8 09:10:06 | 只看该作者
现在是在考虑:如果写到服务器端,我一下搞他个10个存储过程导过去,那久之服务器不就成垃圾箱了吗?即便优化了我的中间层.
飘飘悠悠 该用户已被删除
6#
发表于 2015-2-25 08:21:11 | 只看该作者
对于数据库来说,查询是数据库的灵魂,那么SQL查询效率究竟效率如何呢?下文将带对SQL查询的相关问题进行讨论,供您参考。
老尸 该用户已被删除
7#
发表于 2015-3-7 18:16:24 | 只看该作者
所以你总能得到相应的升级版本,来满足你的需求。
变相怪杰 该用户已被删除
8#
发表于 2015-3-15 11:13:10 | 只看该作者
需要注意的一点,也是我使用过程中发现的一个问题。在建立function->schema->table后,如果在现有的分区表上建立没有显式声明的聚集索引时,分区表会自动变为非分区表。这一点很让我纳闷。
admin 该用户已被删除
9#
发表于 2015-3-22 00:26:31 | 只看该作者
groupby子句可以将查询结果分组,并返回行的汇总信息Oracle按照groupby子句中指定的表达式的值分组查询结果。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-30 00:06

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表