我写了这个sql查询来搜索表:
SELECT * FROM TableName WHERE Name LIKE '%spa%'
该表包含以下行:
我想知道如何编辑此查询,以便返回如下排序结果:
2温泉度假村
3 Spa酒店
1太空公司
4个备件
表示首先包含确切单词的项目,然后是类似单词。
答案 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