INNER JOINとOUTER JOINの違いは何ですか?


35

私はSQLを初めて使用しますが、これら2つのJOINタイプの違いを知りたいですか?

SELECT * 
FROM user u
INNER JOIN telephone t ON t.user_id = u.id

SELECT * 
FROM user u
LEFT OUTER JOIN telephone t ON t.user_id = u.id

いつどちらを使用すればよいですか?


6
これはDBAの質問として当てはまりますか?これは私にとってはコーディングの質問のようです。
BlackICE


@ David、VtCは、サイトにとって間違っていると思われる場合。いつでも再開できます。
jcolebrand

3
これは素晴らしい質問であり、サイトに非常に適していると思います。
datagod

これは、DBパフォーマンスを微調整するためにスリーブなしのDBAなしでDBAから移動する必要があります
。P– AmDB

回答:


32
  • インナーには参加するだけで参加したキーがであるレコードを選択します両方指定したテーブルを。
  • 左外部結合最初のテーブルからすべてのレコード、および接合のキーに一致する第二のテーブル内の任意のレコードを選択します。
  • 右の外部結合第二のテーブルからすべてのレコード、および接合のキーに一致する最初のテーブル内のすべてのレコードを選択します。

最初の例では、ユーザーの電話レコードが少なくとも1つ存在する場合にのみ、ユーザーと電話番号のリストを返します。

2番目の例では、すべてのユーザーのリストと利用可能な場合は電話レコードを返します(利用できない場合はNULL、電話の値を取得します)。


13

誰かがこの質問をするたびに、答えがあります:http : //www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

それがあなたの理解に役立つことを願っています、


3
私は20年間結合を扱ってきましたが、これらの図は私を混乱させているように見えました。
ホーガン

3
私は@Hoganと一緒です-ven図はこれの最良の説明ではありません..どの組み合わせが返されるかを示すグリッドの方が良いでしょう。
ジョー

示しているのは、ベン図が理解できないということだけです。それらは結合のタイプに完全に関連していますが、それらは結合の新しい人々の理解を助けるツールであることを心に留めておいてください。すでに別の概念を念頭に置いて結合を学習している場合は、見慣れないものに見えます。これは問題ありませんが、図の有用性を示す良い指標でもありません。
ジェームズライアン

@jamesryanは真実ではなく、完全に関連していない、結合は交差と結合ではなくセットのデカルト積に似ているデカルト積の側面。
ウィル

1
私は強く反対し、ベン図にはすでに非常に明確に定義された解釈があり、交差点と結合が設定されています。一意でないキーを介して結合する場合、結合はこの解釈に適合しません。ベン図の解釈が広すぎると思います。
ウィル

8

インナーには参加基準への参加に基づいて合成することができ返す行を。外部結合 ...戻りこれらおよびすべての行の    ための第一のテーブルから... ジョイン、左    のための第二のテーブルから... 右ジョイン    ...のために、両方のテーブルから完全ジョイン




どちらを使用するかを選択することは、必要なデータを決定することです。たとえば、電話のuser_idがuserのidと一致するレコードのみが必要な場合は、内部結合を使用します。一致する電話エントリがないユーザーの行も含める場合は、左結合が適切です。

詳細については、StackOverflowに関するこの質問を参照してください。


7

以下のような2つのテーブルがある場合:

Table1 :   A1    B1          Table2  :    B2     C2 
           -     -                        -      -
           1     2                        1      1
           2     4                        2      4
           3     5                        5      2

Inner Joinを使用すると、以下が得られます。

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2

Full Outer Joinを使用すると、以下が得られます。

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
NULL   NULL    1       1

左外部結合を使用すると、以下が得られます。

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL

6

外部結合は、結果にヌルを生成するように明示的に設計されているため、一般的には避ける必要があります。関係的に言えば、それは一種のショットガン結婚です。問題のテーブルが組合の通常の要件に適合していなくても、テーブルを強制的に組合に入れます。これは、実際には、ユニオンを実行する前に1つまたは両方のテーブルにNULLをパディングすることにより、最終的にそれらを通常の要件に適合させます。ただし、次の例のように、nullではなく適切な値を使用してパディングを行うべきではない理由はありません。

SELECT SNO , PNO 
FROM   SP 
UNION  
SELECT SNO , 'nil' AS PNO 
FROM   S 
WHERE  SNO NOT IN ( SELECT SNO FROM SP )

または、次のように、SQLの外部結合演算子とを組み合わせて使用​​すると、同じ結果が得られCOALESCEます。

SELECT SNO , COALESCE ( PNO , 'nil' ) AS PNO 
FROM ( S NATURAL LEFT OUTER JOIN SP ) AS TEMP

「SQLおよびリレーショナル理論:正確なSQLコードの記述方法」の外部結合(4.6)についてのコメント(CJ日付)


5

内部結合は、表示される結果がキーが両方のテーブルにある結果のみである結合です。外部結合は、1つのテーブルのすべてのキーの結果を表示します。左結合は最初のテーブルから、右結合は2番目のテーブルから表示されます。例えば:

table1に次の主キーとデータのペアがあるとします:(1、a)、(2、b)、(3、c)

また、table2には次の主キーとデータのペアがあるとしましょう:(1、fun)、(3、can)、(4、happen)

したがって、主キーでtable1をtable2に内部結合すると、次の結果のトリプレットが得られます(共通主キーが最初、最初のテーブルの2番目のアイテムが2番目、2番目のテーブルの2番目のアイテムが3番目):(1、a、fun)、( 3、c、缶)

主キーでtable1をtable2に左外部結合すると、次の結果のトリプレットが生成されます(上記と同じ形式):(1、a、fun)、(2、b、NULL)、(3、c、can)

主キーでtable1をtable2に右外部結合すると、次の結果のトリプレットが生成されます(上記と同じ形式):(1、a、fun)、(3、c、can)、(4、NULL、happen)

これがコンセプトをきちんと説明することを願っています。


4

もう少し直感的に説明してみましょう。

内部結合には、1つ以上の電話と電話番号を持つユーザーが表示されます。

左外部結合には、電話のない「ユーザー」が追加でリストされます。


4

何をいつ使用するかを尋ねたので、クエリのシナリオを以下に示します-要件に応じて使用するものを選択します。

データ:

テーブルユーザーには10個のレコードがあります。テーブルPhonenoには6つのレコードがあります(1対1の関係。つまり、PhoneNoのエントリはUsersのエントリを1つだけ参照し、PhoneNoのエントリはUsersの特定のエントリのみを参照できます)。

要件1:すべてのユーザーに電話番号を表示します。電話番号のないユーザーを無視します。

クエリ:

SELECT u.uid, u.name, p.phonno 
  FROM user u 
INNER JOIN phones p ON p.uid = u.uid

結果:電話番号を持つ6人のユーザーを表示します

要件2:すべてのユーザーに電話番号を表示します。ユーザーに電話ディスプレイ「N / A」がない場合(利用不可)

クエリ:

SELECT u.uid, u.name, ifnull(p.phonno,'N/A') 
  FROM user u 
LEFT OUTER JOIN phones p ON p.uid = u.uid

結果:

10件すべてのレコードを表示します

注:ifnullは、null値を変換するMySql構文です。この関数を使用して、phonnoがヌルのときにdbエンジンに「N / A」を表示させました。他のDBMSを使用している場合は、適切な機能を探してください。SQL Serverでは、CASEステートメントを使用する必要があります。

これがお役に立てば幸いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.