INNER JOIN の一部で LIKE 句を使用する
-
09-06-2019 - |
質問
ストアド プロシージャ/クエリを構築するときに、INNER JOIN の一部として LIKE 基準を使用できますか、使用する必要がありますか?正しい質問をしているかわかりませんが、説明させてください。
テキストを含む列で検索するキーワードのリストを取得するプロシージャを作成しています。私がコンソールに座っている場合は、次のように実行します。
SELECT Id, Name, Description
FROM dbo.Card
WHERE Description LIKE '%warrior%'
OR
Description LIKE '%fiend%'
OR
Description LIKE '%damage%'
しかし、ストアド プロシージャで「厳密に型指定された」リスト解析を行うために私が少し前に覚えたトリックは、リストをテーブル変数/一時テーブルに解析し、それを適切な型に変換してから、そのテーブルに対して INNER JOIN を実行することです。最終的な結果セットに。これは、たとえば整数 ID のリストをプロシージャに送信するときにうまく機能します。最終的には次のようなクエリになります。
SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblExclusiveCard ON dbo.Card.Id = @tblExclusiveCard.CardId
このトリックを文字列のリストで使用したいと思います。ただし、特定のキーワードを探しているので、LIKE 句を使用します。したがって、理想的には、最終的なクエリは次のようになると考えています。
SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + @tblKeyword.Value + '%'
これは可能ですか?/推奨されますか?
このようなことを行うより良い方法はありますか?
条項の両端にワイルドカードを入れているのは、カードテキストに「大魔神」、「獣戦士」、「直接ダメージ」、「戦闘ダメージ」という用語が使われているからです。
パフォーマンスに応じて、指定したクエリを使用するか、全文キーワード検索を使用して同じタスクを実行できるという印象を受けます。
テキスト検索したいフィールドに対してサーバーにテキスト インデックスを作成させる以外に、他に何かする必要がありますか?
解決
最初のクエリは機能しますが、その列のインデックスは無視されるため、テーブル全体のスキャンが必要になります。すべての LIKE 句を生成するには、動的 SQL を実行する必要もあります。
SQL Server を使用している場合は全文検索を試すか、次のいずれかを確認してください。 ルシーン 実装。ジョエルは最近、それによる成功について語った。
他のヒント
これを試して
select * from Table_1 a
left join Table_2 b on b.type LIKE '%' + a.type + '%'
このやり方は理想的ではありません。慎重に使用してください。
全文検索を探しているようです。カードの説明に対して一連のキーワードをクエリして、ヒットするものを見つけたいからですか?正しい?
個人的に、私は以前にそれをやったことがあり、それは私にとってうまくいきました。私が確認できる唯一の問題は、インデックスのない列に関する問題である可能性がありますが、where 句にも同じ問題が発生すると思います。
私からのアドバイスは、この 2 つの間の実行計画を見てください。すべての優れたプログラミングの問題と同様に、状況に応じてどちらが優れているかは異なると思います。
@ディリーO
このテーブルはどれくらいの大きさですか?
説明フィールドのデータ型は何ですか?
どちらかが小さい場合、全文検索は過剰になります。
@ディリーO
もしかしたらあなたが探している答えではないかもしれませんが、私はスキーマの変更を推奨します...
提案されたスキーマ:
create table name(
nameID identity / int
,name varchar(50))
create table description(
descID identity / int
,desc varchar(50)) --something reasonable and to make the most of it alwase lower case your values
create table nameDescJunc(
nameID int
,descID int)
これにより、ボルトオン ソリューションを実装することなくインデックスを使用できるようになり、データがアトミックに保たれます。
関連している: タグまたはタグ付けに推奨される SQL データベース設計
ちょっと拾ったトリック 「厳密に型指定された」リスト解析を行うには ストアドプロシージャは、 テーブル変数/一時テーブルへのリスト テーブル
ここでほのめかしているのは、含めるキーワードを表に入れてから使用することだと思います 関係分割 一致を検索します (除外する単語に別のテーブルを使用することもできます)。SQL での実際の例については、を参照してください。 Joe Celko によるキーワード検索.
それを試してみてください...
select * from table11 a inner join table2 b on b.id like (select '%'+a.id+'%') where a.city='abc'.
それは私にとってはうまくいきます。:-)
パフォーマンスは、使用する実際のサーバー、データのスキーマ、データ量によって異なります。現在のバージョンの MS SQL Server では、そのクエリは問題なく実行されるはずです (MS SQL Server 7.0 にはその構文に問題がありましたが、 SP2で対処されました).
そのコードをプロファイラーを通して実行しましたか?パフォーマンスが十分に速く、データに適切なインデックスが設定されていれば、準備は完了です。
LIKE '%fiend%' はシークを使用しませんが、LIKE 'fiend%' はシークを使用します。単純なワイルドカード検索は検索可能ではありません
これを試して;
SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' +
CONCAT(CONCAT('%',@tblKeyword.Value),'%') + '%'