问一个高级点的数据库查询的问题咯,看看有没有那位大锅知道的

时间:2022-06-01 22:07:29
实际问题也不算复杂,就是关于数据库查询时拼音输入的模糊查询问题。

举个简得的例子,比如有一张表
id       xm       xb  
1       张三       男
2       李四       男
3       王二麻子     男

一般来说如果在TextBox里面输入“张三”,然后在这个表里进行查询,这样的东西可能谁都会,直接构造一个“select * from table where xm like '%张三%'”的SQL查询语句就OK了,但是现在要做的不是这个,现在要实现的是输入“ZS”就能把所有xm字段中拼音首字母为“ZS”的字段查出来,也就是输入“ZS”就能查出“张三”这条记录,输入“LS”就能查出“李四”这条记录。

注意,有个前提,那就是表里并没有关于姓名拼音的字段,而且现在也不可能在表里再去追加这么一个字段。

我的基本想法是参考拼音输入法的做法在输入“ZS”的时候首先获得拼音首字母为“Z”和“S”的所有汉字,拼音为“Z”的汉字有“在,字,子,做……”,拼音为“S”的汉字有“三,所,送,四……”等等,然后查询的时候构造“select * from table where left(xm,1) in ('在','字',…………)”这样的SQL语句,不过这样做貌似效率不高。

另外就是SQL 里面用Order by对xm字段排序时显然是按照拼音字母顺序排序的,不知道有没有办法直接利用这个原理来搞。

或者那位大锅有更好的办法,大家不妨讨论一下。

8 个解决方案

#1


建个拼音码对照表,
建个函数求拼音码 py(Strpara)
Py(xm) like '%zs%'

#2


哈哈哈 这个东东 俺在DOS时代 使用Dbase或Fox时 字段多了拼音 只为了快速查找 免得输入中文麻烦

姓名:张三  简码:ZS

#3


这个好像在SQL版有答案...借花献佛找了个
if object_id('[pactinfo]') is not null drop table [pactinfo]
go
create table [pactinfo]([ID] int,[pactname] varchar(4))
insert [pactinfo]
select 1,'正常' union all
select 2,'中国' union all
select 3,'做饭' union all
select 4,'加发'

---引用前辈们的一个函数---
create function   f_GetPy(@str   nvarchar(4000)) 
returns   nvarchar(4000) 
as 
begin 
declare   @strlen   int,@re   nvarchar(4000) 
declare   @t   table(chr   nchar(1)   collate   Chinese_PRC_CI_AS,letter   nchar(1)) 
insert   into   @t(chr,letter) 
    select   '吖 ', 'A '   union   all   select   '八 ', 'B '   union   all 
    select   '嚓 ', 'C '   union   all   select   '咑 ', 'D '   union   all 
    select   '妸 ', 'E '   union   all   select   '发 ', 'F '   union   all 
    select   '旮 ', 'G '   union   all   select   '铪 ', 'H '   union   all 
    select   '丌 ', 'J '   union   all   select   '咔 ', 'K '   union   all 
    select   '垃 ', 'L '   union   all   select   '嘸 ', 'M '   union   all 
    select   '拏 ', 'N '   union   all   select   '噢 ', 'O '   union   all 
    select   '妑 ', 'P '   union   all   select   '七 ', 'Q '   union   all 
    select   '呥 ', 'R '   union   all   select   '仨 ', 'S '   union   all 
    select   '他 ', 'T '   union   all   select   '屲 ', 'W '   union   all 
    select   '夕 ', 'X '   union   all   select   '丫 ', 'Y '   union   all 
    select   '帀 ', 'Z ' 
    select   @strlen=len(@str),@re= ' ' 
    while   @strlen> 0 
    begin 
        select   top   1   @re=letter+@re,@strlen=@strlen-1 
            from   @t   a   where   chr <=substring(@str,@strlen,1) 
            order   by   chr   desc 
        if   @@rowcount=0 
            select   @re=substring(@str,@strlen,1)+@re,@strlen=@strlen-1 
    end 
    return(@re) 
end 


---查询---
select 
  * 
from 
  [pactinfo]
where
  left(dbo.f_GetPy(pactname),1)='Z'

---结果---
ID          pactname 
----------- -------- 
1           正常
2           中国
3           做饭

#4


3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。

#5


引用 4 楼 vbreport 的回复:
3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。


哈哈有没有想过拼音字库打包发布的问题?

#6


引用 2 楼 cbm666 的回复:
哈哈哈 这个东东 俺在DOS时代 使用Dbase或Fox时 字段多了拼音 只为了快速查找 免得输入中文麻烦

姓名:张三 简码:ZS


问一个高级点的数据库查询的问题咯,看看有没有那位大锅知道的 都说了不能加这样的字段了,看题不仔细  问一个高级点的数据库查询的问题咯,看看有没有那位大锅知道的

3楼确实是好方法,学习咯 

#7


引用 4 楼 vbreport 的回复:
3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。

3楼的也不是什么隐性字段,拼音码啥的和那玩意扯不上关系,人家利用的是字符串比较功能来做的,"吖"是拼音首字母为A的第一个汉字,"八"是拼音首字母为B的第一个汉字,假定有一个汉字X,只要"吖"<=X<“八”,那么这个字的拼音首字母就是A,反之,如果输入拼音字母A,那么这个汉字就必然大于等于"吖"而且小于“八”,然后就可以直接去数据库里查xm字段内容>="吖"且小于“八”的记录,实质原理还是和Order by排序原理是一样的,只不过是找出了各拼音对应的首个汉字而已。

当然这只是处理了第一个字母的问题,剩下的按照这个原理稍微处理一下就是了。

#8


引用 4 楼 vbreport 的回复:
3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。

真的想不到,你帮过我,我真的很想帮你啊,但我们学sql没这么难的,懂得在vb中用数据库就已经很不错,但我也学习了,谢谢

#1


建个拼音码对照表,
建个函数求拼音码 py(Strpara)
Py(xm) like '%zs%'

#2


哈哈哈 这个东东 俺在DOS时代 使用Dbase或Fox时 字段多了拼音 只为了快速查找 免得输入中文麻烦

姓名:张三  简码:ZS

#3


这个好像在SQL版有答案...借花献佛找了个
if object_id('[pactinfo]') is not null drop table [pactinfo]
go
create table [pactinfo]([ID] int,[pactname] varchar(4))
insert [pactinfo]
select 1,'正常' union all
select 2,'中国' union all
select 3,'做饭' union all
select 4,'加发'

---引用前辈们的一个函数---
create function   f_GetPy(@str   nvarchar(4000)) 
returns   nvarchar(4000) 
as 
begin 
declare   @strlen   int,@re   nvarchar(4000) 
declare   @t   table(chr   nchar(1)   collate   Chinese_PRC_CI_AS,letter   nchar(1)) 
insert   into   @t(chr,letter) 
    select   '吖 ', 'A '   union   all   select   '八 ', 'B '   union   all 
    select   '嚓 ', 'C '   union   all   select   '咑 ', 'D '   union   all 
    select   '妸 ', 'E '   union   all   select   '发 ', 'F '   union   all 
    select   '旮 ', 'G '   union   all   select   '铪 ', 'H '   union   all 
    select   '丌 ', 'J '   union   all   select   '咔 ', 'K '   union   all 
    select   '垃 ', 'L '   union   all   select   '嘸 ', 'M '   union   all 
    select   '拏 ', 'N '   union   all   select   '噢 ', 'O '   union   all 
    select   '妑 ', 'P '   union   all   select   '七 ', 'Q '   union   all 
    select   '呥 ', 'R '   union   all   select   '仨 ', 'S '   union   all 
    select   '他 ', 'T '   union   all   select   '屲 ', 'W '   union   all 
    select   '夕 ', 'X '   union   all   select   '丫 ', 'Y '   union   all 
    select   '帀 ', 'Z ' 
    select   @strlen=len(@str),@re= ' ' 
    while   @strlen> 0 
    begin 
        select   top   1   @re=letter+@re,@strlen=@strlen-1 
            from   @t   a   where   chr <=substring(@str,@strlen,1) 
            order   by   chr   desc 
        if   @@rowcount=0 
            select   @re=substring(@str,@strlen,1)+@re,@strlen=@strlen-1 
    end 
    return(@re) 
end 


---查询---
select 
  * 
from 
  [pactinfo]
where
  left(dbo.f_GetPy(pactname),1)='Z'

---结果---
ID          pactname 
----------- -------- 
1           正常
2           中国
3           做饭

#4


3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。

#5


引用 4 楼 vbreport 的回复:
3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。


哈哈有没有想过拼音字库打包发布的问题?

#6


引用 2 楼 cbm666 的回复:
哈哈哈 这个东东 俺在DOS时代 使用Dbase或Fox时 字段多了拼音 只为了快速查找 免得输入中文麻烦

姓名:张三 简码:ZS


问一个高级点的数据库查询的问题咯,看看有没有那位大锅知道的 都说了不能加这样的字段了,看题不仔细  问一个高级点的数据库查询的问题咯,看看有没有那位大锅知道的

3楼确实是好方法,学习咯 

#7


引用 4 楼 vbreport 的回复:
3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。

3楼的也不是什么隐性字段,拼音码啥的和那玩意扯不上关系,人家利用的是字符串比较功能来做的,"吖"是拼音首字母为A的第一个汉字,"八"是拼音首字母为B的第一个汉字,假定有一个汉字X,只要"吖"<=X<“八”,那么这个字的拼音首字母就是A,反之,如果输入拼音字母A,那么这个汉字就必然大于等于"吖"而且小于“八”,然后就可以直接去数据库里查xm字段内容>="吖"且小于“八”的记录,实质原理还是和Order by排序原理是一样的,只不过是找出了各拼音对应的首个汉字而已。

当然这只是处理了第一个字母的问题,剩下的按照这个原理稍微处理一下就是了。

#8


引用 4 楼 vbreport 的回复:
3楼的没错,但是拼音码字段可做成隐性的,就是用户表面上看不到这个字段,拼音码的生成都是自动生成的。

真的想不到,你帮过我,我真的很想帮你啊,但我们学sql没这么难的,懂得在vb中用数据库就已经很不错,但我也学习了,谢谢