2010-12-10 110 views
0

我正在尋找一種方法來使用Coldfusion在多個關鍵字的sql表中搜索多個列。我目前有以下代碼,一半工作。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列,名字和姓氏的關鍵字輸入到一個文本框。關鍵字使用cfloop標籤進行分解。

此代碼確實會生成結果,但如果在一列或兩列中未找到2個或更多關鍵字,則當前不會刪除結果。

例如,假設我想搜索史蒂夫史密斯,當我輸入史蒂夫時,它顯示了史蒂夫的行。史密斯也是如此。如果我輸入史蒂夫史密斯,它仍然顯示正確的行。

當我輸入類似史蒂夫喬布斯的東西時,它會出錯。鍵入這個仍然顯示史蒂夫史密斯什麼時候不應該。有沒有人有線索如何解決這個問題?

感謝您提前提供任何幫助。 Chris

+0

是否有理由不能在'WHERE'子句中將'OR'更改爲'AND'? – JNK 2010-12-10 13:58:56

+0

你想要什麼結果「史密斯史蒂夫」? – 2010-12-10 14:12:15

+0

我可以改變條件,嘗試所有不同的變化,但都不提供正確的結果。史蒂夫史密斯,我希望它顯示結果,我不希望它顯示史蒂夫喬布斯的結果。謝謝 – Chris 2010-12-10 14:19:15

回答

2

克里斯,你可以運行一個另類「或」 SQL,

我認爲你的問題的核心是你的邏輯當前在說「顯示所有記錄中FirstName或LastName與搜索字符串中某個單詞相匹配的記錄」。您允許某人搜索「馬修馬克盧克約翰」作爲一個字符串,將任何這些姓名的人拉進來,而不是將搜索詞作爲單一名稱。

由於僅在firstName上匹配,這導致記錄「Steve Jobs」出現搜索='Steve Smith'的事實。聽起來像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> 
+0

感謝Mujimu,這工作完美,現在已經實現了! – Chris 2010-12-13 09:32:49

+0

很高興協助... – mujimu 2011-05-05 16:33:54

+0

這很好,但爲了別人的利益,我沒有得到我的搜索「福特獵鷹」的回報,直到我在值的前面添加了「%」=「#字#%」 「,即值=」%#word#%「 – user460114 2016-04-25 23:13:30

1

你用LIKE包裝LIKE子句的兩側告訴我你真的想要一些模糊匹配。我會跳過SQL WHERE語句,而是使用全文解決方案。選項包括:

  1. 數據庫全文索引:SQL Server,Oracle和MySQL都有解決方案。
  2. 搜索引擎:ColdFusion的9艘船既Verity的和SOLR

這些選項要麼會讓你的生活更容易,避免了複雜的和/或類似的邏輯,就需要在一個SQL引進WHERE子句達到一些類似的效果。

+0

感謝你們,我一直在使用Coldfusion很長一段時間,但只在初學者水平。我已經看到Verity的相關信息,但對於它的工作原理還沒有太多的線索,或者我可以如何使用它。另一個問題是即時使用共享主機,所以這會受到影響?此外,這個查詢是AJAX repsonse的一部分。 – Chris 2010-12-10 15:48:31

+1

共享主機可能是設置Verity/SOLR的一個問題,您需要與您的提供商討論。可能更容易在數據庫端獲得全文索引設置。無論哪種情況,您都可以使用這些「模糊搜索」解決方案之一來獲取employee表的主鍵列表,然後運行SQL語句以使用IN子句檢索這些鍵。在這兩種情況下,仍然可以通過AJAX格式從服務器發回響應。另外,你使用的是什麼數據庫? – orangepips 2010-12-10 17:00:06

+0

我們正在使用MySQL5 – Chris 2010-12-13 09:28:54

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> 

如果搜索只有一個字爲