如何使SQL搜索查询更强大?

时间:2009-03-25 02:20:08

标签: sql mysql sql-server sql-server-2005 tsql

我写了这个sql查询来搜索表:

SELECT * FROM TableName WHERE Name LIKE '%spa%'

该表包含以下行:

  1. Space Company。
  2. 水疗度假村。
  3. 温泉酒店。
  4. 备件。
  5. WithoutTheKeyword。
  6. 我想知道如何编辑此查询,以便返回如下排序结果:

      

    2温泉度假村

         

    3 Spa酒店

         

    1太空公司

         

    4个备件

    表示首先包含确切单词的项目,然后是类似单词。

6 个答案:

答案 0 :(得分:10)

类似

Select * from TableName where Name Like 'Spa%'
ORDER BY case when soundex(name) = soundex('Spa') then '1' else soundex(name) end

应该可以正常工作。

实际上这会更好用

Select * from TableName where Name Like 'Spa%'
ORDER BY DIFFERENCE(name, 'Spa') desc;

FWIW我做了一些快速测试,如果'Name'在NONCLUSTERED INDEX中,SQL将使用索引并且不进行表扫描。此外,LIKE似乎比charindex使用更少的资源(返回不太理想的结果)。在sql 2000上测试过。

答案 1 :(得分:5)

我认为,您认为您的架构几乎消除了对这些类型的查询的索引的任何用处?

一个很大的问题是你的“LIKE'%spa%'”。任何以通配符开头的“LIKE”键都是自动表扫描。

<小时/> 编辑: 我读了你的问题,说有一个字段名称,字段值类似于“1 Space Company”,“2 Spa resort”等,后面跟着一个单词。而且你需要在搜索键前面使用通配符才能超过数字部分。 (这是为了澄清我的第一个评论。)我是否正确猜测?

答案 2 :(得分:1)

以下应该做必要的事情,但效率很低,做两个全表选择,它还依赖于你用空格分隔的完全匹配。我认为FullText索引会有所帮助,但这有其自身的开销。

select distinct * from
(
Select * from TableName 
   where CHARINDEX('spa ', Name) > 0
   or CHARINDEX(' spa', Name) > 0
Union
Select * from TableName 
  where Name Like '%spa%'
)

答案 3 :(得分:1)

离开顶部示例,至少在MSSQL2005中,将CLUSTERED更改为NONCLUSTERED将使其执行表扫描。 CLUSTERED为您提供索引搜索。看起来它符合问题的条件。

CREATE TABLE tblTest(ID INT, colname VARCHAR(20) )
CREATE CLUSTERED INDEX tstidx1_tblTest ON tblTest(colname);
INSERT tblTest SELECT 1,'Space Company'
INSERT tblTest SELECT 2,'Spa Resort'
INSERT tblTest SELECT 3,'Spa Hotel'
INSERT tblTest SELECT 4,'Spare Parts'
INSERT tblTest SELECT 5,'WithoutTheKeyword'

SELECT * FROM tblTest WHERE colname LIKE 'Spa%'
ORDER BY DIFFERENCE(colname,'Spa') DESC;

DROP TABLE tblTest

答案 4 :(得分:1)

您基本上需要(精确地)定义您的排名功能。如果你有一排“The Spa”怎么办?还是“spa.com”?一旦定义了,就需要将该逻辑放入ORDER BY子句中。例如:

SELECT
    name
FROM
    Some_Table
WHERE
    name LIKE '%spa%'
ORDER BY
    CASE
        WHEN name LIKE '% ' + @search_word + ' %' THEN 1   -- Notice the spaces
        ELSE 2
    END,
    name

或者,您可以编写排名函数并使用:

SELECT
    name
FROM
    Some_Table
WHERE
    name LIKE '%' + @search_word + '%'
ORDER BY
    dbo.GetNameMatchRank(name, @search_word)

非常大的结果集上的效果可能不会太大,因此这种方法取决于您预期的搜索结果大小。

答案 5 :(得分:-1)

这应该有效:

Select * from TableName where Name Like '%spa%'
ORDER BY Name