2009-09-06 12 views
36

テーブルAとテーブルBの2つのテーブルがあり、結合を実行したいが、一致条件は、A 'の列がBの列のようなものでなければならない。 Bの列:sqlの結合でlikeを使用する方法は?

たとえば、Aの列が 'foo'の場合。 Bの列が 'fooblah'、 'somethingfooblah'、または 'foo'のいずれかである場合、結合は一致します。私は標準的な文のようにワイルドカードを使う方法を知っていますが、結合をするときに混乱します。これは理にかなっていますか?ありがとう。 MySQLでは

答えて

16

あなたは試みることができる:もちろん

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

を、それが全表スキャンを行うだろうので、これは大規模な非効率的なクエリになります。

更新:CONCATで、

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE '%'+ a.column +'%' 

をLIKE使用:LIKE使用

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON INSTR(b.column, a.column) > 0 

:ここINSTRを使用して証明


create table A (MYCOL varchar(255)); 
create table B (MYCOL varchar(255)); 
insert into A (MYCOL) values ('foo'), ('bar'), ('baz'); 
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo'); 
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar'); 
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%'); 
+-------+------------------+ 
| MYCOL | MYCOL   | 
+-------+------------------+ 
| foo | fooblah   | 
| foo | somethingfooblah | 
| foo | foo    | 
| bar | barblah   | 
| bar | somethingbarblah | 
| bar | bar    | 
+-------+------------------+ 
6 rows in set (0.38 sec) 
+1

ありがとうございます。私は同じ機能を実現しますが、効率を上げますか? –

+0

これはあなたがやる方法です。より効率的にする必要がある場合は、テーブルBのMYCOLフィールドにインデックスを付けることができます。 –

+0

MyISAMテーブルタイプを使用している場合は、フルテキストインデックスを試して、それが役立つかどうかを確認できます。一般的にはフルテキスト検索はMySQLの強みではありません。フルテキスト検索がアプリケーションのコア部分である場合、Apache Lucene - http://lucene.apache.org/java/docs/ – Asaph

63

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%') 

すべてのオプションで、あなたはおそらく、あなたは大文字と小文字の区別のために気にすることなく試合を取得していることを確認するために比較する前に大文字に列の値をドライブしたいと思うことをマインド:

SELECT * 
    FROM (SELECT UPPER(a.column) 'ua' 
     TABLE a) a 
    JOIN (SELECT UPPER(b.column) 'ub' 
     TABLE b) b ON INSTR(b.ub, a.ua) > 0 

最も効率的なのに最終的に依存しますEXPLAIN plan出力。

JOIN句は、WHERE句と同じです。 JOINの構文は、標準化されているため、ANSI JOINとも呼ばれます。私は非ANSI LEFT JOINの例を気にするつもりはない

SELECT * 
    FROM TABLE a, 
     TABLE b 
WHERE INSTR(b.column, a.column) > 0 

:などの非ANSIを見て参加します。 ANSI JOIN構文の利点は、テーブルを結合しているものを、実際にWHERE句で起きているものと区別することです。

+0

LIKEとINSTRの間の最速は何ですか(ドメイン名など)? – Meloman

5

これはあなたが頻繁に行う必要があります何かがある場合は...あなたは例えば、テーブルBへの挿入時に、あなたがゼロを書くことができ、テーブルAとB

との関係を非正規化することができますか部分マッピングに基づいてBからAにマッピングするjuncionテーブルへのより多くのエントリ。同様に、いずれかの表を変更すると、この関連性が更新されます。

これは、テーブルAとテーブルBの変更頻度によって異なります。それらがかなり静的である場合、INSERTでヒットを取ることは、SELECTで繰り返しヒットしてもそれほど苦痛ではありません。

+2

それは良い解決策ですが、それを非正規化と呼ぶのは正確ではありません。 –

+2

十分に公正です。それをジャンクション・テーブルと呼んでください –

1

ジョインで条件付き条件を使用するのは、Where句とはまったく異なります。テーブル間のカーディナリティによって、結合節とWhere節の間に差異が生じる可能性があります。

たとえば、外部結合で類似条件を使用すると、結合にリストされている最初の表のすべてのレコードが保持されます。Where節で同じ条件を使用すると、暗黙的に内部結合への結合が変更されます。レコードは一般に、Where句で条件比較を行うためには両方のテーブルに存在する必要があります。

私は一般的に、以前の回答の1つで与えられたスタイルを使用します。

tbl_A as ta 
    LEFT OUTER JOIN tbl_B AS tb 
      ON ta.[Desc] LIKE '%' + tb.[Desc] + '%' 

このようにして、結合タイプを制御できます。

関連する問題