2010-12-10 30 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つ以上のキーワードが見つからない場合、結果は削除されません。

たとえば、Steve Smithを検索する場合、Steveに入力するとSteveの行が表示されます。スミスも同様です。私がスティーブスミスを入力すると、正しい行が表示されます。

私はSteve Jobsのようなものを入力すると間違っています。これを入力すると、スティーブ・スミスはそれを避けるべきです。誰かがこれを回避するための手がかりを持っていますか?

ご協力いただきありがとうございます。 Chris

+0

'WHERE'節で' OR'を 'AND'に変更できない理由はありますか? – JNK

+0

「スミス・スティーブ」にはどんな結果が欲しいですか? –

+0

私は条件を変更することができます、すべての異なるバリエーションを試してみましたが、すべてが正しい結果を提供していません。スティーブスミスと私は結果を表示したい、私はそれをスティーブジョブズの結果を表示したい。ありがとう – Chris

答えて

2

検索されている場合は、代わりの「OR」SQLを実行することができ、

あなたの問題の核心は、あなたのロジックが現在、「FirstNameまたはLastNameが検索文字列内の単語の1つに一致するすべてのレコードを表示する」ということです。あなたは、誰かが "Matthew Mark Luke John"を検索することを許可しています。

これは、firstNameの一致のみのために、 'Steve Jobs'レコードがsearch = 'Steve Smith'のために表示されるという事実を引き起こします。 SQLロジックのような音が広すぎます。

検索する代わりに、一致する複数の名前のリストではなく、文字列を完全な名前(名+姓)として扱うように思えます。ただし、複数の単語が提供されている場合は、ANY以外のすべての単語に一致するレコードをすばやく絞り込む必要があります。

名前は複雑なものになることがあります。姓または名は複数の単語になります。これは若干の困難をもたらす。

望ましい結果:

  • 検索「アレン」 - 「アレン・スミスは、」最初と最後の両方の名前が一致したとの記録 を育てる「アレン
  • 検索の姓または名を持つレコード を持ち出します「アレン」および/または「スミスの

このクエリは、任意の検索文字列内の単語の#が、何らかの形で各単語に一致する唯一のショーのレコードが(いずれかの名前を検索することができますことができますに対する オーダー、例えば。最初の最後または最後)。これはおそらくあなたが望むものです。

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

ありがとうムジム、これは完全に動作し、今実装しました! – Chris

+0

助けてくれて嬉しいです... – mujimu

+0

これは素晴らしいですが、他の人の利益のために、値 "FRONT of value ="#word#%に "%"を追加するまでは、 "Ford Falcon" "すなわち、値="%#単語#% " – user460114

1

あなたがLIKE句の両端をパーセントでラップしていると、あなたは本当にいくつかのファジーアサインマッチングが必要だと私に伝えます。私はSQL WHEREステートメントでスキップし、代わりにフルテキスト解決策を使用します。オプションは次のとおりです。

  1. データベースフルテキストインデックス作成:SQL Server、Oracle、およびMySQLにはすべてソリューションがあります。
  2. 検索エンジン:VerityのとSOLRの両方を使用したColdFusion 9隻の船

これらのオプションのどちらかは、あなたの生活がより簡単になり、あなたはSQL WHERE句で導入する必要があるだろう、複雑なAND/OR LIKEロジックを回避しますいくつかの同様の効果を達成する。

+0

ありがとう、私はかなりの時間のColdfusionを使用していますが、初心者レベルでのみ。私はVerityについての情報を見たことがありますが、それがどのように動作するか、またはどのように私がそれを利用できるかについての多くの手掛かりはありません。もう1つの問題は共有ホスティングを使用しているためですが、これは影響を受けますか?また、このクエリはAJAXのrepsonseの一部です。 – Chris

+1

Verity/SOLRの設定に関しては、共有ホスティングが問題になる可能性があります。プロバイダと相談する必要があります。おそらくDB側でフルテキストインデックス設定を取得する方が簡単です。いずれの場合も、これらのファジー検索ソリューションのいずれかを使用して従業員テーブルの主キーのリストを取得し、SQL文を実行してIN句を使用して検索します。どちらの場合でも、AJAX形式の応答をサーバーから送信することは可能です。また、どのデータベースを使用していますか? – orangepips

+0

私たちは現在MySQL5を使用しています – Chris

0

「firstname」と「lastname」と入力して検索し、スタブで検索をあいまいにするなど、いくつかの前提を設定します。スミス...スミス、スミザーズなどを返すかもしれません。あなたが本当に鍛冶屋、ironsmithを一致させたい場合は、など、あなたの大手%に戻すことができ

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

1ワードのみがクリス

関連する問題