web-dev-qa-db-ja.com

LEFT JOINを使用する場合とINNER JOINを使用する場合

私はいつもLEFT JOINsとINNERsと組み合わせて、異なるページで同じことを行うはずのいくつかのコードで同じタイプのクエリを実行することがよくあります。ここに行く:

SELECT ac.reac, pt.pt_name, soc.soc_name, pt.pt_soc_code
FROM
  AECounts ac
  INNER JOIN 1_low_level_term llt on ac.reac = llt.llt_name
  LEFT JOIN 1_pref_term pt ON llt.pt_code = pt.pt_code
  LEFT JOIN 1_soc_term soc ON pt.pt_soc_code = soc.soc_code
LIMIT 100,10000

それは私が取り組んでいるものです:

私は多くのように見えます:

SELECT COUNT(DISTINCT p.`case`) as count
FROM FDA_CaseReports cr
  INNER JOIN ae_indi i ON i.isr = cr.isr
  LEFT JOIN ae_case_profile p ON cr.isr = p.isr

これは、左も同様に内部のように見えるかもしれません。

33
cerd

キャッチはありますか?はい。左結合は外部結合の一種であり、内部結合は内部結合の一種です。

違いを示す例を次に示します。基本データから始めます。

mysql> select * from j1;
+----+------------+
| id | thing      |
+----+------------+
|  1 | hi         |
|  2 | hello      |
|  3 | guten tag  |
|  4 | ciao       |
|  5 | buongiorno |
+----+------------+

mysql> select * from j2;
+----+-----------+
| id | thing     |
+----+-----------+
|  1 | bye       |
|  3 | tschau    |
|  4 | au revoir |
|  6 | so long   |
|  7 | tschuessi |
+----+-----------+

そして、ここでは、内部結合と左結合の違いがわかります。

mysql> select * from j1 inner join j2 on j1.id = j2.id;
+----+-----------+----+-----------+
| id | thing     | id | thing     |
+----+-----------+----+-----------+
|  1 | hi        |  1 | bye       |
|  3 | guten tag |  3 | tschau    |
|  4 | ciao      |  4 | au revoir |
+----+-----------+----+-----------+

うーん、3列。

mysql> select * from j1 left join j2 on j1.id = j2.id;
+----+------------+------+-----------+
| id | thing      | id   | thing     |
+----+------------+------+-----------+
|  1 | hi         |    1 | bye       |
|  2 | hello      | NULL | NULL      |
|  3 | guten tag  |    3 | tschau    |
|  4 | ciao       |    4 | au revoir |
|  5 | buongiorno | NULL | NULL      |
+----+------------+------+-----------+

うわー、5列!どうした?

left joinなどの外部結合は、一致しない行を保持します。したがって、id 2および5の行は、左結合クエリによって保持されます。残りの列はNULLで埋められます。

つまり、左結合と内部結合は互換性がありません。

101
Matt Fenwick

大まかな答えは次のとおりです。これは、結合についての私の考えです。これが前述の数学の問題のために非常に正確な答えよりも役立つことを願っています... ;-)

内部結合は、行の戻り値のセットを絞り込みます。外部結合(左または右)は​​、返される行数を変更しませんが、可能であれば追加の列を「選択」します。

最初の例では、結果は1_low_level_termテーブルに指定された条件に一致するAECountsの行になります。次に、それらの行に対して、試行1_pref_termおよび1_soc_termに結合します。ただし、一致するものがない場合、行は残り、結合された列はヌルになります。

12
rob

INNER JOINは、両方のテーブルに一致する値がある行のみを返しますが、LEFT JOINは、RIGHTテーブルに一致する行がない場合でもLEFTテーブルからすべての行を返します。

簡単な例

TableA
ID   Value
1    TableA.Value1
2    TableA.Value2
3    TableA.Value3

TableB
ID   Value
2    TableB.ValueB
3    TableB.ValueC

INNER JOINは以下を生成します。

SELECT a.ID,a.Value,b.ID,b.Value 
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID

a.ID    a.Value            b.ID    b.Value
2       TableA.Value2      2       TableB.ValueB
3       TableA.Value3      3       TableB.ValueC

LEFT JOINは以下を生成します。

SELECT a.ID,a.Value,b.ID,b.Value 
FROM TableA a LEFT JOIN TableB b ON b.ID = a.ID

a.ID    a.Value            b.ID    b.Value
1       TableA.Value1      NULL    NULL
2       TableA.Value2      2       TableB.ValueB
3       TableA.Value3      3       TableB.ValueC

ご覧のとおり、ID = 1のTableBに一致する行がない場合でも、LEFT JOINにはID = 1のTableAの行が含まれますが、TableBに一致する行がないため、INNER JOINは行を除外します

HTH

5
philf2b

初心者の場合、それは私が1だったときに助けてくれたからです。内部結合は常に左または右結合のサブセットであり、これらはすべて完全結合のサブセットです。基本的な考え方を理解するのに役立ちました。

1
Scott

結合条件に一致する両方のテーブルに表示される結果のみが必要な場合は、内部結合を使用します。

テーブルAのすべての結果が必要な場合は左結合を使用しますが、テーブルBにテーブルAのレコードの一部に関連するデータがある場合は、同じクエリでそのデータを使用することもできます。

両方のテーブルのすべての結果が必要な場合は、完全結合を使用します。

1
Seung Bae Im