web-dev-qa-db-ja.com

左、右、外部、内部結合の違いは何ですか?

これらのさまざまな結合をすべて区別する方法を考えています...

530
MrM

簡単な例 StudentsテーブルとLockersテーブルがあるとしましょう。 SQLでは、結合で最初に指定したテーブルStudents _ left _ テーブルで、2番目のテーブルLockers _ right _ テーブルです。

各生徒はロッカーに割り当てることができるので、LockerNumberテーブルにStudent列があります。一人のロッカーに複数の生徒がいる可能性がありますが、特に学年の初めに、ロッカーのいない入学生や、割り当てられていないロッカーがあるかもしれません。

この例では、 100人の学生がいて 70人がロッカーを持っているとします。あなたは全部で 50人のロッカーを持っています 、そのうち40人は少なくとも1人の学生がいて、10人のロッカーは学生がいません。

内部結合 は、「 すべての生徒にロッカーを付けて表示する 」と同じです。
ロッカーのいない生徒、または生徒のいないロッカーは行方不明です。
70行を返します

LEFT OUTER JOIN は " 全生徒を表示し、対応するロッカーがあれば "を表示します。
これは一般的な学生リストである場合もあれば、ロッカーのない学生を識別するために使用される場合もあります。
100行を返します

RIGHT OUTER JOIN は " すべてのロッカーを見せ、もしあれば彼らに割り当てられた学生を "にする。
これは、生徒が割り当てられていないロッカー、または生徒が多すぎるロッカーを識別するために使用できます。
80行を返します (40人のロッカーにいる70人の学生のリスト、および1人の学生がいない10人のロッカー)

FULL OUTER JOIN は愚かで多分あまり使われないでしょう。
すべての生徒とすべてのロッカーを見せて、できる限り一致させる
110行を返します (ロッカーのいない生徒を含む100人すべての生徒。学生のいない10人のロッカー)

CROSS JOIN このシナリオでもかなり馬鹿げています。
Studentsテーブルのリンクされたlockernumberフィールドを使用しないので、実際に存在するかどうかにかかわらず、基本的にすべての可能性のあるStudent-to-Lockerペアリングの巨大なリストになります。
5000行を返します (100人の学生×50人のロッカー)空いているロッカーと新入生を合わせるための出発点として(フィルタリングで)役に立つかもしれません。

771
BradC

結合には3つの基本タイプがあります。

  • INNER joinは2つのテーブルを比較し、一致がある場合にのみ結果を返します。 1番目のテーブルからのレコードは、2番目のテーブルの複数の結果と一致すると重複します。内部結合は結果セットを小さくする傾向がありますが、レコードが重複する可能性があるため、これは保証されません。
  • CROSS joinは2つのテーブルを比較し、両方のテーブルから行の可能なすべての組み合わせを返します。この種の結合からは意味がない場合もあるので、多くの結果が得られる可能性があるため、注意して使用してください。
  • OUTER joinは2つのテーブルを比較し、一致がある場合はデータを返し、それ以外の場合はNULL値を返します。 INNER結合と同様に、他のテーブルの複数のレコードと一致すると、一方のテーブルの行が複製されます。 OUTER結合は、結果セットを大きくする傾向があります。これは、それ自体ではレコードをレコードから削除しないためです。いつ、どこでNULL値を追加するかを決定するには、OUTER結合も修飾する必要があります。
    • LEFTは、1番目のテーブルのすべてのレコードを何に関係なく保持し、2番目のテーブルが一致しないときにNULL値を挿入することを意味します。
    • RIGHTは反対を意味します。2番目のテーブルのすべてのレコードを何に関係なく保持し、1番目のテーブルが一致しない場合はNULL値を挿入します。
    • FULLは、両方のテーブルのすべてのレコードを保持し、一致しない場合はどちらかのテーブルにNULL値を挿入することを意味します。

多くの場合、OUTERキーワードは構文から省略されます。その代わりに、それは単に "LEFT JOIN"、 "RIGHT JOIN"、または "FULL JOIN"になります。これは、INNERおよびCROSS結合がLEFT、RIGHT、またはFULLに関しては意味がないためです。したがって、これらはOUTER結合を明確に示すのに十分です。

これは、それぞれの型を使いたい場合の例です。

  • INNER: "Invoice"テーブルからすべてのレコードを、対応する "InvoiceLines"と共に返します。これは、すべての有効な請求書に少なくとも1行が含まれることを前提としています。
  • OUTER:特定の請求書のすべての "InvoiceLines"レコードと、それに対応する "InventoryItem"レコードを返します。これは、すべてのInvoiceLineにIventoryItemが含まれるわけではないため、サービスも販売しているビジネスです。
  • CROSS:10行の数字テーブルがあり、各行には '0'から '9'までの値が入ります。結合する日付範囲テーブルを作成して、範囲内の各日に1つのレコードができるようにします。このテーブルをそれ自身とクロス結合することで、必要なだけ連続した整数を作成することができます(10から1の累乗で始めると、各結合は指数に1を加えます)。次に、DATEADD()関数を使用してこれらの値を範囲の基準日に追加します。
137
Joel Coehoorn

4種類しかありません。

  1. 内部結合 :最も一般的なタイプ。結合条件に一致する入力行のペアごとに出力行が生成されます。
  2. 左外部結合 :右のテーブルに一致する行が見つからない行がある場合、左のテーブルの値を含む行が出力されることを除いて、内部結合と同じです。右側の表の各値にNULLを付けます。これは、左側のテーブルのすべての行が少なくとも1回は出力に現れることを意味します。
  3. 右外部結合 :テーブルの役割が逆になる点を除いて、左外部結合と同じです。
  4. 完全外部結合 :左右の外部結合の組み合わせ。両方のテーブルのすべての行が少なくとも1回は出力に表示されます。

「クロス結合」または「デカルト結合」は、結合条件が指定されていない内部結合であり、すべての行ペアが出力されます。

FULL JOINを指摘してくれたRusselHに感謝します。

47
j_random_hacker

SQL JOINSの違い:

非常に覚えやすいです:

INNER JOINは両方のテーブルに共通のレコードのみを表示します。

OUTER JOIN両方のテーブルの内容は、一致するかどうかにかかわらず、すべてマージされます。

LEFT JOINLEFT OUTER JOIN - と同じです(一致する右テーブルレコードを持つ最初の(最も左の)テーブルからレコードを選択します)。

RIGHT JOINRIGHT OUTER JOIN - と同じです(左から2番目のテーブルのレコードが一致するレコードを2番目(右端)のテーブルから選択します)。

enter image description here

15
Laxmi

チェックアウト ウィキペディアで(SQL)に参加

  • 内部結合 - 2つのテーブルがあると、内部結合は両方のテーブルに存在するすべての行を返します。
  • left/right(outer)join - 2つのテーブルがあなたのジョインの左右どちらかのテーブルに存在するすべての行を返し、さらに反対側からの行がjoin句がマッチした場合に返されます。それらの列

  • Full Outer - 与えられた2つのテーブルがすべての行を返し、左右どちらかの列がない場合はnullを返します

  • クロス結合 - デカルト結合が行われ、慎重に使用しないと危険な場合があります。

9
JoshBerke

LEFT JOINRIGHT JOINOUTER JOINの型です。

INNER JOINがデフォルトです。両方のテーブルの行が結合条件に一致する必要があります。

4
RussellH

内部結合 :両方のテーブルのデータがある場合に、行のみを表示します。

外部結合 (left/right) left/right テーブルのすべての結果を、対になった行( s )で表示します。 it 存在する ない​​。

3
Pethő Jonatán

それをもっと見やすくすることは助けになるかもしれません。一例です。

表1:

ID_STUDENT STUDENT_NAME

1               Raony
2               Diogo
3               Eduardo
4               Luiz

表2

ID_STUDENT LOCKER

3               l1
4               l2
5               l3

私がするとき私が得るもの:

-Inner join of Table 1 and Table 2: 

    - Inner join returns both tables merged only when the key 
      (ID_STUDENT) exists in both tables

    ID_STUDENT       STUDENT_NAME      LOCKER   

        3               Eduardo          l1
        4               Luiz             l2

-Left join of Table 1 and Table 2:

    - Left join merges both tables with all records form table 1, in 
      other words, there might be non-populated fields from table 2

    ID_ESTUDANTE    NOME_ESTUDANTE     LOCKER   

        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2

-Right join of table 1 and table 2:

    - Right join merges both tables with all records from table 2, in 
      other words, there might be non-populated fields from table 1

    ID_STUDENT        STUDENT_NAME     LOCKER   

        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

-Outter join of table 1 and table 2:

    - Returns all records from both tables, in other words, there
      might be non-populated fields either from table 1 or 2.

    ID_STUDENT        STUDENT_NAME     LOCKER   
        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3
2
lfvv

最初に参加することを理解する必要がありますか?複数のテーブルを接続し、結合されたテーブルから特定の結果を得ます。これを行う最も簡単な方法は cross join です。

TableAには2つの列AとBがあるとしましょう。そしてtableBには3つの列CとDがあります。クロスジョインを適用すると、多くの意味のない行が生成されます。次に、実際のデータを取得するために主キーを使用して照合する必要があります。

左: 左のテーブルからのすべてのレコードと右のテーブルからの一致したレコードを返します。

右: 左結合と反対に戻ります。右側のテーブルからすべてのレコードを、左側のテーブルから一致したレコードを返します。

内部: これは交差点のようです。両方のテーブルから一致したレコードのみを返します。

アウター: そしてこれは労働組合みたいです。両方のテーブルからすべての利用可能なレコードを返します。

場合によっては、すべてのデータが必要なわけではなく、共通のデータまたはレコードだけが必要な場合もあります。これらのjoinメソッドを使って簡単に手に入れることができます。左右の結合も外部結合であることを忘れないでください。

クロスジョインを使うだけですべてのレコードを取得できます。しかし、何百万ものレコードになるとそれは高価になる可能性があります。だから、左、右、内側または外側の結合を使用してそれを簡単にする。

ありがとう

1
HM Nayem