Как сделать поисковый запрос sql более мощным? - PullRequest
7 голосов
/ 25 марта 2009

Я написал этот SQL-запрос для поиска в таблице:

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

Таблица содержит следующие строки, например:

  1. Космическая Компания.
  2. Спа-курорт.
  3. Санаторий.
  4. Запасные части.
  5. WithoutTheKeyword.

Я хочу знать, как редактировать этот запрос, чтобы он возвращал результаты, отсортированные следующим образом:

2 Спа-курорт

3 санатория

1 космическая компания

4 Запасные части

Означает элементы, которые содержат точное слово, а затем аналогичные.

Ответы [ 6 ]

10 голосов
/ 25 марта 2009

что-то вроде

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.

5 голосов
/ 25 марта 2009

Вы понимаете, я полагаю, что ваша схема почти исключает какую-либо полезность индексов для таких запросов?

Большая проблема - ваше "НРАВИТСЯ"% spa% '". Любой ключ "LIKE", начинающийся с символа подстановки, является автоматическим сканированием таблицы.


РЕДАКТИРОВАТЬ: Я прочитал ваш вопрос, чтобы сказать, что есть одно поле, Имя, со значениями полей, например, «1 космическая компания», «2 Спа-курорт» и т. Д., За которым следуют слова. И вам нужно было подстановочный знак перед вашим ключом поиска, чтобы пройти номер части. (Это поясняет мой первый комментарий.) Правильно ли я угадываю или нет?
1 голос
/ 25 марта 2009

Вам в основном нужно определить (точно), какова ваша функция ранжирования на самом деле. Что делать, если у вас есть строка "Спа". или "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)

Производительность на очень больших наборах результатов может быть не слишком высокой, поэтому этот подход зависит от ожидаемых результатов поиска.

1 голос
/ 25 марта 2009

Начиная с верхнего примера, по крайней мере, в 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
1 голос
/ 25 марта 2009

Следующее должно сделать необходимое, но это неэффективно, делать два полных выбора таблицы, и это также зависит от вашего точного соответствия, разделенного пробелами. Я думаю, что индексация 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%'
)
0 голосов
/ 25 марта 2009

Это должно работать:

Select * from TableName where Name Like '%spa%'
ORDER BY Name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...