Поиск слов в индексе SQL Server

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

Проблема в том, что я хочу искать слова в столбце, но не хочу сопоставлять части.

Например, мой столбец может содержать названия компаний:
Mighty Muck Miller and Partners Inc.
Компания Boy & Butter Breakfast

Теперь, если я ищу "Miller", я хочу найти первую строку. Но если я ищу "iller", я не хочу его находить, потому что нет слова, начинающегося с "iller". При поиске «Break» должно быть найдено «Boy & Butter Breakfast company», поскольку одно слово начинается с «Break».

Поэтому, если я попытаюсь использовать

WHERE BusinessName LIKE %Break%

он найдет слишком много хитов.

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

(лучше всего подойдет LINQ, подойдет и обычный SQL)

Важно! Пробелы далеко не единственные разделители! Косая черта, двоеточие, точки, все не буквенно-цифровые символы должны учитываться, чтобы это работало!


person Sam    schedule 01.10.2008    source источник


Ответы (5)


SQL Server 2000 или выше.

SELECT *
  FROM dbo.TblBusinessNames
 WHERE BusinessName like '%[^A-z^0-9]Break%' -- In the middle of a sentence
    OR BusinessName like 'Break%'            -- At the beginning of a sentence

Справочник по ключевым словам для LIKE: http://msdn.microsoft.com/en-us/library/aa933232(SQL.80).aspx

person Ricardo C    schedule 02.10.2008
comment
Ого, круто, вот и все - мне придется добавить несколько иностранных символов (äöüÄÖÜß), но это намного лучше, чем создавать причудливые процедуры регулярных выражений! - person Sam; 07.10.2008

У вас будет много разделителей слов: пробел, табуляция, начало строки, круглые скобки, точки, запятые, восклицательные/вопросительные знаки и т. д. Итак, довольно простое решение — использовать регулярное выражение в предложении WHERE. (И это будет намного эффективнее, чем просто использовать ИЛИ для каждого возможного разделителя, о котором вы только можете подумать.)

Поскольку вы упомянули LINQ, вот статья, в которой описывается, как выполнять эффективные запросы регулярных выражений с помощью SQL. Сервер.

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

EDIT: Видел, что вы отредактировали свой вопрос. Когда записываете регулярное выражение, легко использовать в качестве разделителя любой небуквенный символ, т.е. [^0-9a-zA-Z] или \W для любого символа, не являющегося словом, \b для любой границы слова и \B для любой границы, не являющейся словом. Или, вместо того, чтобы сопоставлять разделители, просто сопоставьте любое слово, то есть \w+. Вот еще один пример того, как кто-то выполняет поиск по регулярным выражениям с помощью SQL Server ( сложнее, чем то, что вам нужно).

person joelhardi    schedule 01.10.2008

Вы упомянули LINQ - вы могли бы сделать что-то вроде...

string myPattern = "% Break%";

var query =
      from b in Business
      where SqlMethods.Like(b.BusinessName, myPattern) 
      select b;

Обратите внимание, что здесь используется пространство имен System.Linq.Data.SqlClient, которое напрямую преобразуется в оператор LIKE без дополнительной обработки.

person Galwegian    schedule 01.10.2008

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

declare @vSearch nvarchar(100)

set @vSearch = 'About'

select * from btTab where ' ' + vText + ' ' LIKE '%[^A-z^0-9]' + @vSearch + '[^A-z^0-9]%'
person jasp    schedule 09.03.2010

person    schedule
comment
Так что мне пришлось бы добавить или нравится для каждого возможного разделителя, например косой черты, двоеточия, точки...? Компания Boy and Butter-Breakfast - person Sam; 01.10.2008
comment
Нет, если у вас больше разделителей (вы указали это позже), то это не очень хорошее решение. Возможно, вы можете попробовать регулярные выражения, если вы используете SQL 2005 или SQL 2008 или думаете о полнотекстовом поиске. - person Biri; 01.10.2008
comment
На самом деле это было в тексте с самого начала (или другие разделители), но, поскольку все пропустили эти три слова, я решил выделить их и дополнительно добавить еще несколько пояснений по этому поводу - извините, они были очень хорошо скрыты заранее. - person Sam; 01.10.2008
comment
Вы можете создать себе «столбец поиска», то есть такой же, как название компании, но где вы замените все свои знаки препинания и т. д. стандартным разделителем, например «|». Вы можете использовать представление для этого. Затем просто найдите «|Break%». - person Codewerks; 02.10.2008
comment
Извините, я тоже пропустил эту часть. Виноват. - person Biri; 02.10.2008