首页 新闻 会员 周边

求助sql server的文本搜索排序问题,望各位大侠指点

0
悬赏园豆:60 [待解决问题]

场景:

需要通过用户输入的姓名关键字来搜索用户。用户输入关键字'x'来搜索用户(数据来源于表[Name字段中]或内存[List<UserInfo>]中)

要求:

得到的结果排序应为:

x

xia

xiao

yx

即:

  1. 包含x字母的结果均应显示出来
  2. 首字母匹配的结果应该排在前面(如x开头)
  3. 在条件2相同的前提下更短的结果应排在前面(如x排在xia前面)
       

各位大侠能否给出一套c#与sql server(2008)的解决方案?


补充:

如果能一起解决中文问题最好,如搜索'x'

得到的结果排序应为:

x

xiani

夏荣

肖小笑

杨星

即将汉字的拼音首字母纳入在内,不知sqlserver是否支持这一特性的搜索?

学习的脚步的主页 学习的脚步 | 初学一级 | 园豆:140
提问于:2011-01-07 15:46
< >
分享
所有回答(3)
0

在中等数据库的情况下要保证效率的话 建议冗余一个字段 一个记录首字的拼音[FirstChar]

select * from table where FirstChar='x' or ( FirstChar='x' and Name like '%x%')

order by  (  )...

order by 的逻辑是 如果是FirstChar='x' 那么给length(Name) -1000 否则 返回 length(Name)

然后从低到高排

这样代码比较简单 效率也还可以

 

当然如果是大数据量(>=1000000 records) 那要做的事情就多了

 

PS: 把长度也冗余出来有助于提高查询性能

PS:如果有分页的话 说不定分开查找性能更好 (前提是首字母命中率足够高)

PS:分表也可以 如果压力太大了 按照首字母分表

听说读写 | 园豆:777 (小虾三级) | 2011-01-07 15:56
0

由于时间缘故没做过多解释

有什么问题及时提出




---------------------准备工作 开始-------------------------------
if object_id('zhuisuos')is not null
drop table zhuisuos
go

create table zhuisuos
(
name
varchar(100)
)
insert into zhuisuos values('xia')
insert into zhuisuos values('dxc')
insert into zhuisuos values('x')
insert into zhuisuos values('xx')
insert into zhuisuos values('xiani')
insert into zhuisuos values('yx')
insert into zhuisuos values('夏荣')
insert into zhuisuos values('肖小笑')
insert into zhuisuos values('杨星')
go

--建立函数
if object_id('fn_getfirstspell')is not null
drop function fn_getfirstspell
go

GO
create function [dbo].fn_getfirstspell
(
@str nvarchar(4000))
returns nvarchar(4000)
as
begin
declare @str_len int,@result nvarchar(4000)
declare @zhuisuo table
(firstspell
nchar(1) collate Chinese_PRC_CI_AS,
letter
nchar(1))
set @str_len=len(@str)
set @result= ' '
insert into @zhuisuo
(firstspell,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 '
while @str_len> 0
begin
select top 1 @result=letter+@result,@str_len=@str_len-1
from @zhuisuo
where firstspell <=substring(@str,@str_len,1)
order by firstspell desc
if @@rowcount=0
select @result=substring(@str,@str_len,1)+@result,@str_len=@str_len-1
end
return(@result)
end

---------------------准备工作 结束-------------------------------

--正式查询

declare @str varchar(10)
set @str='x'
create table #result
(name
varchar(100) null,id int null,lens int null)

insert into #result
select name,1,len(name) from zhuisuos
where name like @str+'%'

insert into #result
select name,2,len(name) from zhuisuos
where name like '%'+@str+'%' and name not like @str+'%'

insert into #result
select name,3,len(name) from zhuisuos
where dbo.fn_getfirstspell (name) like @str+'%' and name not like @str+'%' and name not like '%'+@str+'%'

insert into #result
select name,4,len(name) from zhuisuos
where dbo.fn_getfirstspell (name) like '%'+@str+'%' and dbo.fn_getfirstspell (name) not like @str+'%'
and name not like @str+'%' and name not like '%'+@str+'%'


select name from #result
order by id,lens
drop table #result
追索 | 园豆:625 (小虾三级) | 2011-01-07 17:27
谢谢您,不过感觉fn_getfirstspell函数的效率可能有点低,不知是否有何提升效率的方法?
支持(0) 反对(0) 学习的脚步 | 园豆:140 (初学一级) | 2011-01-08 12:47
把函数里临时表代码删掉 直接在数据库建一张物理的拼音转换表(注:加上主键,索引) 然后函数from后面直接搜索这张表,这种方法可提高几倍速度。你试试能不能达到你的要求
支持(0) 反对(0) 追索 | 园豆:625 (小虾三级) | 2011-01-10 15:50
0

可以通过linq高模糊查询,简单方便!

一直在跑wu | 园豆:150 (初学一级) | 2011-02-27 09:35
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册