Используйте предложение LIKE в части внутреннего соединения - PullRequest
13 голосов
/ 21 августа 2008

Можно / нужно ли использовать критерии LIKE как часть INNER JOIN при построении хранимой процедуры / запроса? Я не уверен, что спрашиваю правильно, поэтому позвольте мне объяснить.

Я создаю процедуру, которая будет принимать список ключевых слов для поиска в столбце, который содержит текст. Если бы я сидел за консолью, я бы выполнил это так:

SELECT Id, Name, Description
  FROM dbo.Card
 WHERE Description LIKE '%warrior%' 
       OR
       Description LIKE '%fiend%' 
       OR 
       Description LIKE '%damage%'

Но уловка, которую я немного подобрал, чтобы выполнить "строго типизированный" анализ списка в хранимой процедуре, состоит в том, чтобы проанализировать список в табличную переменную / временную таблицу, преобразовать его в правильный тип и затем выполнить INNER JOIN. против этой таблицы в моем окончательном наборе результатов. Это прекрасно работает при отправке, скажем, списка целочисленных идентификаторов в процедуру. Я получаю последний запрос, который выглядит так:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblExclusiveCard ON dbo.Card.Id = @tblExclusiveCard.CardId

Я хочу использовать этот трюк со списком строк. Но так как я ищу определенное ключевое слово, я собираюсь использовать предложение LIKE. Поэтому в идеале я думаю, что мой окончательный запрос будет выглядеть так:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + @tblKeyword.Value + '%'

Возможно ли это / рекомендуется?

Есть ли лучший способ сделать что-то подобное?


Причина, по которой я ставлю символы подстановки на обоих концах пункта, заключается в том, что в текстах карт используются термины «архи-злодей», «воин-зверь», «прямой урон» и «боевой урон».

У меня складывается впечатление, что в зависимости от производительности я могу либо использовать указанный запрос, либо использовать полнотекстовый поиск по ключевым словам для выполнения той же задачи?

Кроме того, чтобы сервер делал текстовый индекс для полей, которые я хочу найти, нужно ли что-нибудь еще делать?

Ответы [ 10 ]

5 голосов
/ 21 августа 2008

Ваш первый запрос будет работать, но потребуется полное сканирование таблицы, потому что любой индекс в этом столбце будет игнорироваться. Вам также потребуется выполнить некоторый динамический SQL, чтобы сгенерировать все ваши предложения LIKE.

Попробуйте полнотекстовый поиск, если вы используете SQL Server, или ознакомьтесь с одной из реализаций Lucene . Джоэл недавно рассказал о своем успехе.

5 голосов
/ 29 января 2013

Попробуйте это

    select * from Table_1 a
    left join Table_2 b on b.type LIKE '%' + a.type + '%'

Эта практика не идеальна. Используйте с осторожностью.

1 голос
/ 27 мая 2015

попробуй ...

select * from table11 a inner join  table2 b on b.id like (select '%'+a.id+'%') where a.city='abc'.

Это работает для меня. :-)

1 голос
/ 01 мая 2009

трюк, который я немного подобрал, иди сделать "строго типизированный" анализ списка в хранимая процедура должна проанализировать список в таблицу переменных / временных таблица

Я думаю, что вы могли бы упомянуть здесь, чтобы поместить ключевые слова для включения в таблицу, а затем использовать реляционное деление для поиска совпадений (также можно использовать другую таблицу для слов, которые следует исключить). Работающий пример в SQL см. Поиск по ключевым словам Джо Селко .

1 голос
/ 21 августа 2008

@ Dillie-O
Насколько большой этот стол?
Каков тип данных поля Описание?

Если любой из них мал, полнотекстовый поиск будет излишним.

@ Dillie-O
Возможно, не тот ответ, который вы искали, но я бы выступил за изменение схемы ...

предложенная схема:

create table name(
    nameID identity / int
   ,name varchar(50))

create table description(
    descID identity / int
   ,desc varchar(50)) --something reasonable and to make the most of it alwase lower case your values

create table nameDescJunc(
    nameID  int
    ,descID int)

Это позволит вам использовать индексы, не прибегая к конкретным решениям, и сохранит ваши данные в элементарном виде.

относящиеся: Рекомендуемый дизайн базы данных SQL для тегов или тегов

1 голос
/ 21 августа 2008

Лично я делал это раньше, и это хорошо сработало для меня. Единственные проблемы, которые я мог видеть, это, возможно, проблемы с неиндексированным столбцом, но я думаю, что у вас возникнет та же проблема с предложением where.

Мой вам совет - просто посмотрите на планы выполнения между ними. Я уверен, что это будет отличаться, какой из них лучше в зависимости от ситуации, как и все хорошие проблемы программирования.

1 голос
/ 21 августа 2008

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

0 голосов
/ 21 мая 2009

Попробуйте это;

SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + 
                                CONCAT(CONCAT('%',@tblKeyword.Value),'%') + '%'
0 голосов
/ 21 августа 2008

LIKE "% fiend%" никогда не будет использовать поиск, как "fiend%". Просто поиск по шаблону не может быть sargable

0 голосов
/ 21 августа 2008

Производительность будет зависеть от фактического сервера, который вы используете, а также от схемы данных и объема данных. В текущих версиях MS SQL Server этот запрос должен работать нормально (MS SQL Server 7.0 имел проблемы с этим синтаксисом, но он был адресован в SP2 ).

Вы запускали этот код через профилировщик? Если производительность достаточно высокая, а данные имеют соответствующие индексы, у вас все должно быть в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...