SQL-запрос - поиск по нескольким ключевым словам по нескольким столбцам - PullRequest
0 голосов
/ 10 декабря 2010

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

<cfquery name="rsSearchEmployees" datasource="#request.database#">
SELECT idn, firstname, lastname
FROM Employees 
WHERE (<cfloop list="#arguments.nameSearchString#" delimiters=" " index="word">firstname LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%#Trim(word)#%" /> OR </cfloop> (1 <> 1))
OR (<cfloop list="#arguments.nameSearchString#" delimiters=" " index="word">lastname LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%#Trim(word)#%" /> OR </cfloop> (1 <> 1))
ORDER BY firstname ASC

Он ищет 2 столбца, имя и фамилию с ключевыми словами, введенными в текстовое поле. Ключевые слова разбиты по тегу cfloop.

Этот код дает результаты, но в настоящее время не удаляет результаты, если в одном или обоих столбцах не найдено 2 или более ключевых слов.

Например, скажем, я хотел найти Стива Смита, когда я набираю Стива, он показывает строку для Стива. То же самое происходит с Смитом. Если я наберу Стив Смит, он все равно покажет строку, которая является правильной.

Это неправильно, когда я набираю что-то вроде Стива Джобса. Печатая это все еще показывает Стив Смит, когда это не должно. Кто-нибудь знает, как это обойти?

Спасибо за любую помощь заранее. Chris

Ответы [ 3 ]

2 голосов
/ 10 декабря 2010

Крис,

Я думаю, что суть вашей проблемы в том, что ваша логика в настоящее время говорит: «Покажите мне все записи, где FirstName или LastName соответствуют одному из слов в строке поиска». Вы позволяете кому-то искать «Мэтью Марк Люк Джон» как строку, чтобы найти людей с ЛЮБЫМИ из этих имен, вместо того, чтобы рассматривать поисковое слово только как одно имя.

Это вызывает тот факт, что запись 'Steve Jobs' появляется для поиска = 'Steve Smith' из-за совпадения только по firstName. Похоже, логика SQL слишком широка.

Звучит так, будто вы хотите, чтобы поиск вместо этого обрабатывал строку как полное имя (имя + фамилия), а не как список из нескольких имен для сравнения. Однако, если предоставляется более одного слова, вы хотите быстро сузить записи, которые соответствуют ВСЕМ словам, не ЛЮБИМЫМ.

Имена могут быть сложными, с именем или фамилией, состоящим из нескольких слов. Это представляет некоторые незначительные трудности.

Желаемый результат:

  • Поиск "Аллен" - воспитывать записи с именем или фамилией Аллена
  • Поиск "Аллен Смит" воспитывает записи с обоими именами и фамилиями против "Аллена" и / или "Смита"

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

SELECT idn, firstname, lastname
FROM Employees 
WHERE 1=1
<cfloop list="#arguments.nameSearchString#" delimiters=" " index="word">
    AND ( firstname like <cfqueryparam cfsqltype="cf_sql_varchar" value="#word#%" />
    OR lastname like <cfqueryparam cfsqltype="cf_sql_varchar" value="#word#%" /> )
</cfloop>
1 голос
/ 10 декабря 2010

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

  1. Полнотекстовая индексация базы данных: SQL Server, Oracle и MySQL имеют решения.
  2. Поисковая система: ColdFusion 9 поставляется как с Verity, так и с SOLR.

Любой из этих вариантов значительно облегчит вашу жизнь и позволит избежать сложной логики «И / ИЛИ КАК», которая вам понадобитсяввести в предложение SQL WHERE для достижения некоторого подобного эффекта.

0 голосов
/ 10 декабря 2010

Делая пару предположений, вроде того, что вы всегда будете вводить «имя» и «фамилию», чтобы искать и что вы хотите нечеткий поиск в заглушке, например. Смит ... возвращает Смит, Смитерс и т. д. это может сделать это. Вы можете вернуть свой лидирующий%, если вы действительно хотите подобрать кузнеца, ирониста и т. Д.

<cfquery name="rsSearchEmployees" datasource="#request.database#">
SELECT idn, firstname, lastname
FROM Employees 
WHERE firstname like <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(word)#%" />
AND lastname like <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(word)#%" />
</cfquery>

вы можете запустить альтернативный "ИЛИ" SQL, если ищется только одно слово

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