Reputation: 68902
I wrote this sql query to search in a table:
SELECT * FROM TableName WHERE Name LIKE '%spa%'
The table contain these row for example:
I want to know how to edit this query so it return the results sorted like this:
2 Spa resort
3 Spa hotel
1 Space Company
4 Spare Parts
Means the items which contain the exact word first then the like ones.
Upvotes: 7
Views: 23765
Reputation: 37645
You realize, I presume, that your schema just about eliminates any usefulness of indexes for these kinds of queries?
A big problem is your "LIKE '%spa%'". Any "LIKE" key starting with a wildcard is an automatic table scan.
Upvotes: 5
Reputation: 47444
You basically need to define (precisely) what your ranking function really is. What if you have a row that is "The Spa." or "spa.com"? Once you have that defined, you need to put that logic into your ORDER BY clause. For example:
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
Alternatively, you could write a ranking function and use that:
SELECT
name
FROM
Some_Table
WHERE
name LIKE '%' + @search_word + '%'
ORDER BY
dbo.GetNameMatchRank(name, @search_word)
Performance on very large result sets may not be too great, so this approach depends on your expected search result sizes.
Upvotes: 1
Reputation: 2793
Going off the top example, at least in MSSQL2005 changing the CLUSTERED to NONCLUSTERED will make it do a table scan. CLUSTERED gives you an index seek. Looks like it matches the conditions of the question.
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
Upvotes: 1
Reputation: 4582
something like
Select * from TableName where Name Like 'Spa%'
ORDER BY case when soundex(name) = soundex('Spa') then '1' else soundex(name) end
should work ok.
actually this will work better
Select * from TableName where Name Like 'Spa%'
ORDER BY DIFFERENCE(name, 'Spa') desc;
FWIW I did some quick tests and if 'Name' is in a NONCLUSTERED INDEX SQL will use the index and doesn't do a table scan. Also, LIKE seems to use less resources than charindex (which returns less desirable results). Tested on sql 2000.
Upvotes: 10
Reputation: 14865
The following should do the necessary, but it's inefficient, doing two full table selects and it also relies on your exact match being delimited by spaces. I think FullText indexing would help, but that has overheads of its own.
select distinct * from
(
Select * from TableName
where CHARINDEX('spa ', Name) > 0
or CHARINDEX(' spa', Name) > 0
Union
Select * from TableName
where Name Like '%spa%'
)
Upvotes: 1
Reputation: 25197
This should work:
Select * from TableName where Name Like '%spa%'
ORDER BY Name
Upvotes: -1