57

テーブル A とテーブル B という 2 つのテーブルがあり、結合を実行したいのですが、一致条件は、A の列が B の列と「似ている」場所でなければなりません。 B:

例: A の列が「foo」の場合。次に、B の列が「fooblah」、「somethingfooblah」、または単に「foo」のいずれかである場合、結合は一致します。標準の like ステートメントでワイルドカードを使用する方法は知っていますが、結合を行うときに混乱します。これは理にかなっていますか?ありがとう。

4

5 に答える 5

95

Using INSTR:

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

Using LIKE:

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

Using LIKE, with CONCAT:

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

Mind that in all options, you'll probably want to drive the column values to uppercase BEFORE comparing to ensure you are getting matches without concern for case sensitivity:

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

The most efficient will depend ultimately on the EXPLAIN plan output.

JOIN句は、句を書くことと同じですWHERE。このJOIN構文は、標準化されているため、ANSI JOIN とも呼ばれます。非 ANSI JOIN は次のようになります。

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

非 ANSI LEFT JOIN の例を気にするつもりはありません。ANSI JOIN 構文の利点は、テーブルを結合しているものと、WHERE句で実際に起こっていることを分離することです。

于 2009-09-06T17:36:13.863 に答える
24

MySQLでは、次のことを試すことができます。

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

もちろん、これは全表スキャンを実行するため、非常に非効率的なクエリになります。

更新:ここに証拠があります


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)
于 2009-09-06T17:22:42.017 に答える
6

これが頻繁に行う必要がある場合は、テーブル A と B の間の関係を非正規化することをお勧めします。

たとえば、テーブル B への挿入時に、部分マッピングに基づいて B を A にマッピングするジャンクション テーブルに 0 個以上のエントリを書き込むことができます。同様に、いずれかのテーブルを変更すると、この関連付けが更新される可能性があります。

これはすべて、テーブル A と B が変更される頻度に依存します。それらがかなり静的である場合、INSERT でのヒットは、SELECT でのヒットの繰り返しよりも痛みが少なくなります。

于 2009-09-06T17:40:24.697 に答える
3

結合で条件付き基準を使用することは、Where 句とは明らかに異なります。テーブル間のカーディナリティによって、Join 句と Where 句に違いが生じる可能性があります。

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

私は通常、以前の回答の 1 つで指定されたスタイルを使用します。

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

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

于 2017-03-09T01:47:46.153 に答える