2014-09-20 150 views
0

我有一个名为infoone的表,其中有两列addresslocationCITYSQL搜索查询与like运算符

我想写一个搜索查询。

如果用户搜索Edmonton,它应该返回所有有城市Edmonton的记录。

如果用户搜索12 main street Edmonton,那么它应该返回所有相应的记录。 12 main street是地址和Edmonton是城市

我已经是继什么查询,

string sql = "select PLACEID,LEFT(CONVERT(NVARCHAR(1000),description),500)+'...' as des1,LOCATIONCITY,ADDRESS,DateT,RENT from infoone where "; 
    sql += "(((address like '%"+txtSearch.Text+"%') or (address like '')) and ((locationcity like '%"+txtSearch.Text+"%') or (locationcity like '')) and ((address LIKE '%"+txtSearch.Text+"%') or (address like '')))"; 

上面的查询,当我搜索不返回任何东西:

main street Edmonton 

用户也将被允许没有城市的搜索如:12th main street

我做错了什么?

请帮

感谢

+1

如果我搜索'')))DROP TABLE infoone --'? – 2014-09-21 03:57:19

回答

2

免费的形式寻找地址是非常困难的。

让我们看看你的例子

Address   locationCity 
12 Main Street Edmonton 
456 Thomas Ave St Martin 

可能searchs

  • 埃德蒙顿 - 如果只有1个字,我们应该认为它是一个城市?如果是这样,用户如何找到圣马丁 ?
  • 埃德蒙顿大街12号 - 现在,你怎么知道埃德蒙顿是这座城市? 用户可以搜索一个街道名称吗?

我建议您的界面接受两列,一个用于地址,一个用于城市,它会使搜索更容易。

where <other conditions> 
AND 
(locationcity like '%CitySearchFld%' and address like '%AddresssSearchFld%') 

无需寻找空的,因为如果用户离开该领域的空白,搜索%%的会匹配所有行

其他考虑

在用户搜索,会发生什么对于

12 Main St 

Edmenton

缩写?拼写错误?

要处理的缩写,我将建立一个一站式的单词列表,这会从地址栏中删除常见缩写,像街,街,大道,大道等等。因此搜索变得

12主要

我不想错过一个记录,因为我不确定它是否是表中的st或Street。

你也可以使用一个函数知道的探测法(本地SQL)或音位(自定义SQL或CLR)来处理拼写错误...

好运

0

这种搜索是如此的困难,但有很多不同的方法可以很好地搜索地址,

最简单的方法是,在这样的完整地址搜索;

SELECT * FROM WHERE美国存托凭证(locationcity + '' +地址)LIKE '%搜索内容%'

,但没有办法知道哪些字是城市与否。

1

我不相信你的where子句在做你的意图。让我们把外串var和重新格式化为可读性:

select PLACEID,LEFT(CONVERT(NVARCHAR(1000),description),500)+'...' as des1 
,LOCATIONCITY,ADDRESS,DateT,RENT 
from infoone 
where(
    ((address like '%"+txtSearch.Text+"%') or (address like '')) 
    -- #1 address must match full text or be blank 
    and 
    ((locationcity like '%"+txtSearch.Text+"%') or (locationcity like '')) 
    -- #2 locationcity must match full text or be blank 
    and 
    ((address LIKE '%"+txtSearch.Text+"%') or (address like '')) 
    -- #3 address must match full text or be blank. Seems a duplicate of #1 
    ) 

这三个与AND将链接在一起,所以这三个条件必须为真为它返回一个结果。

最起码,WHERE子句可能被重新编写是这样的:

select PLACEID,LEFT(CONVERT(NVARCHAR(1000),description),500)+'...' as des1 
,LOCATIONCITY,ADDRESS,DateT,RENT 
from infoone 
where(
    (address like '%"+txtSearch.Text+"%') 
    or 
    (locationcity like '%"+txtSearch.Text+"%') 
    or 
    (address + locationcity like '%"+txtSearch.Text+"%') 
    or 
    (address + ' ' + locationcity like '%"+txtSearch.Text+"%') 
    ) 

这将返回一个记录,如果文本匹配的任一地址或locationcity找到,或者如果文本匹配他们结合时,或与空间结合。

这就是为什么你没有收到你提供的样本输入的结果。使用上面的代码,当搜索“main street edmonton”时,您应该在最后的第四个条件中获得匹配结果

您应该先使用SSMS中的非动态SQL处理代码, @TEXT),一旦它根据你的文本参数返回你想要的结果,你可以将它切换到动态。把它写成一个要执行的SQL字符串只是在你正在开发你的SQL代码的时候复杂化。

对于更广泛的解决方案,你可能想看看全文搜索: http://msdn.microsoft.com/en-us/library/ms142571.aspx

这打散字符串为单个单词,并为这些词的搜索,它可以让你拿出加权猜测和比赛排名。它甚至可以让你使用类似术语使用词库,所以如果有人搜索“123 Main St.”和“123 Main Street”在数据库中,它会发现那些是匹配的。