SQL查询 - 搜索多列的多个关键字

时间:2010-12-10 13:55:38

标签: sql coldfusion keyword

我正在寻找一种使用Coldfusion搜索具有多个关键字的sql表中的多个列的方法。我目前有以下代码,其中一半是有效的。

<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列,firstname和lastname,并在文本框中输入关键字。关键字使用cfloop标记进行细分。

此代码确实会生成结果,但如果在一列或两列中找不到2个或更多关键字,则目前不会删除结果。

例如,假设我想搜索史蒂夫史密斯,当我输入史蒂夫时,它显示了史蒂夫的排。史密斯也是如此。如果我输入Steve Smith,它仍会显示正确的行。

当我输入史蒂夫乔布斯这样的东西时出错了。打印这个仍然显示史蒂夫史密斯不应该。有没有人知道如何解决这个问题?

提前感谢您的帮助。 克里斯

3 个答案:

答案 0 :(得分:2)

克里斯,

我认为你的问题的核心是你的逻辑当前正在说“向我显示FirstName或LastName与搜索字符串中的一个词匹配的所有记录”。你允许某人搜索“Matthew Mark Luke John”作为一个字符串,以便用任何这些名字来吸引人,而不是仅将搜索词视为单个名称。

由于firstName上的匹配,这导致记录'Steve Jobs'出现在search ='Steve Smith'这一事实。听起来像SQL逻辑太宽泛了。

听起来您希望搜索将字符串视为全名(名字+姓氏),而不是要匹配的多个名称列表。但是,如果提供了多个单词,您希望快速缩小与所有单词匹配的记录,而不是任何单词。

名字可能很复杂,名字或姓氏都是多字。这会带来一些小麻烦。

期望的结果:

  • 搜索“艾伦” - 调出记录 姓名为'Allen'的第一个或最后一个姓名
  • 搜索“艾伦史密斯”提出记录 与姓名匹配 反对'艾伦'和/或'史密斯'

此查询将允许搜索字符串中的任何#个单词,但仅显示以某种方式匹配每个单词的记录(允许以任何顺序搜索名称,例如,First Last或Last First)。这可能就是你想要的。

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 :(得分:1)

你将LIKE子句的两边都用百分比包裹起来告诉我你真的想要一些模糊匹配。我会跳过SQL WHERE语句并使用全文解决方案。选项包括:

  1. 数据库全文索引:SQL Server,Oracle和MySQL都有解决方案。
  2. 搜索引擎:ColdFusion 9附带Verity和SOLR
  3. 这些选项中的任何一个都会使您的生活更轻松,并避免在SQL WHERE子句中引入复杂的AND / OR LIKE逻辑以实现类似的效果。

答案 2 :(得分:0)

做出一些假设,比如你将总是输入“名字”和“姓氏”来寻找,并且你想要对存根进行模糊搜索,例如史密斯......回复史密斯,史密斯等等。如果你真的想要匹配铁匠,铁匠等,你可以放回领先的%。

<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>

如果只搜索一个单词

,你可以运行另一个“OR”SQL