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


4672

また、どのようLEFT JOINRIGHT JOINしてFULL JOINフィットしますか?


64
以下の回答とコメントおよびそれらの参照のうち、ベン図が演算子を表す方法を実際に説明しているのは1つだけです。円の交差領域はA JOIN Bの行のセットを表します。各円に固有の領域は、 A JOIN Bに参加せず、他のテーブルに一意の列を追加するテーブルの行はすべてNULLに設定されます。(そして、ほとんどがAとBへの円のあいまいな対応を与えます。)
philipxy 2014年

1
以下の理論に基づく答えから、実際のアプリケーションにジャンプします。私は、実験データを使用して、プロセッサ設計でベンチマークを実行することがよくあります。2つ以上のハードウェアオプション間で結果を比較したいことがよくあります。INNER JOINは、すべての実験で正常に実行されたベンチマークのみが表示されることを意味します。OUTER JOINは、一部の構成で実行に失敗したものを含むすべての実験を表示できることを意味します。このような実験の失敗と成功を確認することが重要です。多くのRDBMSがそれを欠いているときに、私がOUTER JOINを取得するためにPerlSQLを書いたことは非常に重要です
Krazy Glew

4
多くの回答がすでに提供されていますが、このチュートリアルが言及されているのを見たことはありません。あなたがベン図を知っているなら、これは素晴らしいチュートリアルです: blog.codinghorror.com/a-visual-explanation-of-sql-joins 私にとって、それは簡単に読めるのに十分簡潔ですが、それでも全体の概念を理解し、すべてを機能させます非常によく。ベン図が何であるかがわからない場合は、それらを学習してください。5〜10分で習得でき、セットの操作とセットの操作の管理を視覚化する必要があるときに役立ちます。
DanteTheSmith

15
@DanteTheSmithいいえ、ここの図と同じ問題に悩まされています。質問と上記のブログ投稿の下の私のコメントを参照してください:「ジェフはコメントの数ページ下のブログを拒否します」。ベン図は要素をセットで示します。これらの図で、セットとは何か、要素は何かを正確に識別してみてください。セットテーブルではなく、要素その行ではありません。また、任意の2つのテーブルを結合できるため、PKとFKは関係ありません。すべての偽物。あなたは何千人もの人がやったことと同じようにやっている- あなたが(間違って)意味がある思う漠然とした印象を得た。
philipxy

3
クリス私はあなたがこの記事を読んでお勧めします。towardsdatascience.com/...を ...とベン図を使用していない答えに(おそらく恵みと1対)受け入れ答えのあなたの選択を変更することを検討してください。現在受け入れられている答えは、あまりにも多くの人々を誤解させています。私たちのコミュニティと知識ベースの質のためにこれを行うことをお勧めします。
コルムバンダル

回答:


6115

非常に一般的なケースである、重複のない列で結合していると仮定します。

  • AとBの内部結合は、AがBと交差する結果、つまりベン図の交差の内部を提供します。

  • AとBの外部結合は、AユニオンBの結果、つまりベン図表ユニオンの外部部分を与えます。

次のような2つのテーブルがあり、それぞれ1つの列とデータがあるとします。

A    B
-    -
1    3
2    4
3    5
4    6

(1,2)はAに固有であり、(3,4)は共通であり、(5,6)はBに固有であることに注意してください。

内部結合

同等のクエリのいずれかを使用した内部結合は、2つのテーブルの共通部分、つまり、2つのテーブルに共通する2つの行を提供します。

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

a | b
--+--
3 | 3
4 | 4

左外部結合

左外部結合は、Aのすべての行に加えて、Bのすべての共通行を提供します。

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4

右外部結合

右外部結合は、Bのすべての行に加えて、Aのすべての共通行を提供します。

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6

完全外部結合

完全外部結合は、AとBの結合、つまりAのすべての行とBのすべての行を提供します。Aの何かがBに対応するデータを持たない場合、Bの部分はnullであり、逆も同様です。その逆。

select * from a FULL OUTER JOIN b on a.a = b.b;

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5

42
値を4にしてテーブルBに別の行を追加することで例を拡張するとよいでしょう。これは、内部結合が等しい行数である必要がないことを示しています。
softveda 09

473
ただし、この説明はすばらしい説明です。AとBの外部結合は、AユニオンBの結果、つまりベン図のユニオンの外部部分を示します。正確に表現されていません。外部結合では、Aの結果がBと交差します。さらに、Aのすべて(左結合)、Bのすべて(右結合)、またはAのすべてとBすべて(完全結合)があります。この最後のシナリオだけが本当にA組合Bです。それでも、よく書かれた説明です。
トーマス

11
FULL JOINはFULL OUTER JOINのエイリアスで、LEFT JOINはLEFT OUTER JOINのエイリアスだと思いますか?
Damian

3
はい、素晴らしい説明です。しかし、なぜ列bの値が正しくないのですか?つまり、5,6ではなく6,5ですか?
Ameer

7
@Ameer、ありがとう。結合では順序が保証されないため、ORDER BY句を追加する必要があります。
マークハリソン

734

ベン図は実際には私にはそれをしません。

たとえば、クロス結合と内部結合の違いは示されていません。より一般的には、さまざまな種類の結合述語の違いが示されていないか、それらがどのように動作するかを推論するためのフレームワークを提供しています。

論理処理を理解するための代替手段はなく、とにかく把握することは比較的簡単です。

  1. クロス結合を想像してみてください。
  2. 評価する onどこ述語評価さにそれらを維持するステップ1からすべての行に対して句をtrue
  3. (外部結合の場合のみ)手順2で失われた外部行を追加します。

(注:実際には、クエリオプティマイザーは上記の純粋に論理的な説明よりも効率的なクエリの実行方法を見つけることができますが、最終結果は同じである必要があります)

まず、完全外部結合のアニメーションバージョンから始めます。さらに説明します。

ここに画像の説明を入力してください


説明

ソーステーブル

ここにリンクの説明を入力

CROSS JOIN(別名デカルト積)から始めます。これにはありませんON句、2つのテーブルの行のすべての組み合わせを返すだけです。

クロスジョインBからA.Color、B.Colourを選択します

ここにリンクの説明を入力

内部結合と外部結合には、 "ON"句の述語があります。

  • 内部結合。クロス結合結果のすべての行について、 "ON"句の条件を評価します。trueの場合、結合された行を返します。それ以外の場合は破棄してください。
  • 左外部結合。内側の結合と同じで、左側のテーブルのどの行にも一致しなかった場合、右側のテーブルの列にはNULL値が出力されます。
  • 右外部結合。内側の結合と同じで、右側のテーブルのどの行にも一致しなかった場合、左側のテーブルの列にはNULL値が出力されます。
  • 完全外部結合。内部結合と同じで、左外部結合と同様に左の一致しない行を保持し、右外部結合と同様に右の一致しない行を保持します。

いくつかの例

A.Colour = B.Colourの内部結合BからA.Colour、B.Colourを選択します。

上記は古典的な等価結合です。

内部結合

アニメーション版

ここに画像の説明を入力してください

A.Colour NOT IN( 'Green'、 'Blue')の内部結合BからA.Colour、B.Colourを選択します

内部結合条件は必ずしも等号条件である必要はなく、両方(またはどちらか一方)のテーブルの列を参照する必要はありません。A.Colour NOT IN ('Green','Blue')クロス結合の各行を評価して戻ります。

インナー2

1 = 1の内部結合BからA.Colour、B.Colourを選択します。

結合条件は、クロス結合結果のすべての行に対してtrueと評価されるため、これはクロス結合とまったく同じです。16行の画像を再度繰り返すことはありません。

A.Colour = B.Colourの左外部結合BからA.Colour、B.Colourを選択します。

外部結合は、左側のテーブルの行(左側の結合の場合)が右側のテーブルの行とまったく結合しない場合を除いて、内部結合と同じ方法で論理的に評価されNULLます。右側の列。

LOJ

SELECT A.Colour、B.Colour from a LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL

これは単に前の結果を制限して、である行のみを返すようにしますB.Colour IS NULL。この特定の場合、これらは右側のテーブルで一致しなかったため保持された行であり、クエリはtableで一致しなかった単一の赤い行を返しますB。これは、反準結合として知られています。

IS NULLnull可能ではないか、結合条件NULLによってこのパターンが正しく機能し、たまたまそのNULL値を持つ行が返されないようにするために値が除外されることが保証されているテスト用の列を選択することが重要です一致しない行に加えて列。

lojはnullです

A.Colour = B.Colourの右側の外部結合Bから、A.Colour、B.Colourを選択します。

右外部結合は、左表の一致しない行を保持し、左側の列をヌル拡張することを除いて、左外部結合と同様に機能します。

ROJ

A.Colour = B.Colourの完全外部結合BからA.Colour、B.Colourを選択します。

完全外部結合は、左と右の結合の動作を組み合わせ、左と右の両方のテーブルから一致しない行を保持します。

FOJ

A.COLORを選択し、B.COLORを完全に外部から結合するB ON 1 = 0

クロス結合のどの行も1=0述部と一致しません。両側のすべての行は、反対側のテーブルの列にNULLを含む通常の外部結合ルールを使用して保持されます。

FOJ 2

COALESCE(A.Colour、B.Colour)を、完全な外部結合B ON 1 = 0からの色として選択します

前のクエリを少し修正するUNION ALLと、2つのテーブルのうちの1つをシミュレートできます。

UNION ALL

A.Colourを選択し、B.Colourを左外部結合B ON A.Colour = B.Colour WHERE B.Colour = 'Green'から選択します。

WHERE句(存在する場合)は論理的に結合の後に実行されることに注意してください。よくあるエラーの1つは、左外部結合を実行してから、一致しない行を除外してしまう右テーブルの条件を含むWHERE句を含めることです。上記は最終的に外部結合を実行します...

LOJ

...そして、「Where」節が実行されます。NULL= 'Green'はtrueと評価されないため、外部結合によって保持された行は(青色の行とともに)最終的に破棄され、結合が内部の行に効果的に変換されます。

LOJtoInner

ColorがGreenであるBの行のみを含め、正しい構文に関係なくAのすべての行を含めることが意図されている場合は、次のようになります。

A.Colour = B.Colour AND B.Colour = 'Green'の左外部結合BからA.Colour、B.Colourを選択します

ここに画像の説明を入力してください

SQLフィドル

SQLFiddle.comでこれらの例をライブでご覧ください


46
これは私にとってはベン図と同様にほとんど機能しませんが、人々はさまざまで異なる学習をすることに感謝します。これは、これまでに見たものとは異なり、非常によく説明された説明であるため、@ ypercubeをサポートしていますボーナスポイントを獲得します。また、JOIN句とWHERE句に条件を追加することの違いを説明する優れた作品。マーティン・スミスさん、ありがとうございます。
Old Pro

22
@OldProベン図は、私が想定している限りは問題ありませんが、クロス結合を表す方法や、等結合などのある種類の結合述語を別のものから区別する方法については何も述べていません。クロス結合結果の各行で結合述語を評価し、外部結合の場合に一致しない行を追加し、最後にwhereを評価するメンタルモデルは、私にとってより効果的です。
マーティン・スミス

18
ベン図は、和集合、交差、差異を表すのに適していますが、結合を表すのには適していません。これらは、非常に単純な結合、つまり結合条件が一意の列にある結合に対して、いくつかの小さな教育的価値があります。
ypercubeᵀᴹ

12
@Arth-いいえ、あなたは間違っています。SQL Fiddle sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/5155これは、ベン図では説明できないものです。
Martin Smith

7
@MartinSmithうわー、同意します、私は完全に間違っています!1対多での作業に慣れすぎています。修正してくれてありがとう。
Arth

188

結合は、2つのテーブルからのデータを結合するために使用され、その結果、新しい一時テーブルになります。結合は、結合を実行するために使用する条件を指定する、述語と呼ばれるものに基づいて実行されます。内部結合と外部結合の違いは、内部結合は結合述語に基づいて実際に一致する行のみを返すことです。たとえば、従業員と場所のテーブルを考えてみましょう:

ここに画像の説明を入力してください

内部結合:- 内部結合は、結合述語に基づいて2つのテーブル( Employee Location)の列の値を組み合わせることにより、新しい結果テーブルを作成します。クエリは、 Employeeの各行を Locationの各行と比較して、結合述語を満たす行のすべてのペアを見つけます。NULL以外の値を照合することにより結合述語が満たされると、一致する Employee Locationの行の各ペアの列値が結果行に結合されます。内部結合のSQLは次のようになります。

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

ここで、SQLを実行した結果は次のようになります。 ここに画像の説明を入力してください

外部結合:- 外部結合では、結合された2つのテーブルの各レコードが一致するレコードを持つ必要はありません。結合されたテーブルは、他の一致するレコードが存在しない場合でも、各レコードを保持します。外部結合は、保持されているテーブルの行(左または右)に応じて、左外部結合と右外部結合にさらに分割されます。

左外部結合:-テーブル Employeeおよび Locationの左外部結合(または単に左結合)の結果には、join-conditionで一致するレコードが見つからない場合でも、常に「左」テーブル( Employee)のすべてのレコードが含まれます。「正しい」テーブル( Location)。上記の表を使用した、左外部結合のSQLは次のようになります。

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

ここで、このSQLを実行した結果は次のようになります。 ここに画像の説明を入力してください

右外部結合:- 右外部結合(または右結合)は、表の扱いが逆になっていることを除いて、左外部結合によく似ています。「正しい」テーブル( Location)のすべての行が、結合されたテーブルに少なくとも1回表示されます。「左」テーブル( Employee)の一致する行が存在しない場合、 Locationに一致しないレコードの Employeeの列にNULLが表示されます。SQLは次のようになります。

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

上記の表を使用して、右外部結合の結果セットがどのようになるかを示すことができます。

ここに画像の説明を入力してください

完全外部結合:- 完全外部結合または完全結合は、結合の結果に一致しない行を含めることで、一致しない情報を保持するために、完全外部結合を使用します。他のテーブルに一致する値があるかどうかに関係なく、両方のテーブルのすべての行が含まれます。

画像ソース

MySQL 8.0リファレンスマニュアル-結合構文

Oracleの結合操作


3
これまでのベストアンサー、代替構文-それが私が探していたものです、ありがとう!
ジョーイ

1
ベン図には誤ったラベルが付けられています。質問と他の回答に対する私のコメントを参照してください。また、この言語のほとんどは貧弱です。例:「NULL以外の値に一致させることで結合述語が満たされると、一致するEmployeeとLocationの行の各ペアの列値が結果行に結合されます。」いいえ、「NULL以外の値を照合することで結合述語が満たされる場合」ではありません。行内の値は、条件が全体として真であるか偽であるか以外には関係ありません。一部の値は、真の条件ではNULLになる可能性があります。
philipxy

明記されていませんが、この図はベン図です。ベン図は、一般に、結合の数学的特性を正確に表したものではありません。ベン図を削除することをお勧めします。
Colm Bhandal

@ColmBhandal:ベン図を削除
ajitksharma

表やERDを含むテキストには、画像やリンクではなく、テキストを使用してください。テキストとして表現できないもの、またはテキストを補うためにのみ画像を使用します。画像の検索やカット&ペーストはできません。凡例/キーと説明を画像とともに含めます。
philipxy

133

内部結合

一致した行のみ、つまりを取得しますA intersect B

ここに画像の説明を入力してください

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

左外部結合

最初のテーブルからすべてのレコードを選択し、結合されたキーに一致する2番目のテーブルのレコードを選択します。

ここに画像の説明を入力してください

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

完全外部結合

2番目のテーブルからすべてのレコードを選択し、結合されたキーに一致する最初のテーブルのすべてのレコードを選択します。

ここに画像の説明を入力してください

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

参考文献


14
ツールの名前は何ですか?行とベン図の数が示されているので、興味深いと思います
Grijesh Chauhan 2014

2
@GrijeshChauhan Yeahしかし、あなたはワインを使ってそれを実行してみることができます。
Tushar Gupta-curioustushar 2014年

2
おお!はい私..私はワインを使用してSQLyogのを使用...もありPlayOnLinux
Grijesh Chauhan

1
あなたのテキストは不明瞭で間違っています。「一致した行のみ」は、AとBのクロス結合からの行であり、取得されるもの(内部結合B)はAとBが交差せず、(左結合B)が交差(右結合B)します。「選択」の行はAクロスA&Bからの行のヌル拡張値からB&への参加から彼らは、A&Bからはありません
philipxy

@ TusharGupta-curioustushar「SQLの例に使用されるテーブル」を含める必要があります
Manuel Jordan

112

簡単な言葉で:

インナーには参加するだけでマッチした行を取得します。

一方、外部結合は、1つのテーブルから一致した行を取得し、他のテーブルのすべての行を取得します。結果は、使用している行によって異なります。

  • :右のテーブルの一致した行と左のテーブルのすべての行

  • :左のテーブルの一致した行と右のテーブルのすべての行、または

  • フル:すべてのテーブルのすべての行。一致するかどうかは関係ありません


1
@nomenこの回答で対処できるわけではありませんが、左右のセット/サークルに(それぞれ)LEFT&RIGHTジョインの行が含まれている場合、INNER JOINは共通部分であり、FULL OUTER JOINは対応するUNION です。PSこの答えは、入力と出力の行については不明です。「左/右のテーブル内」と「左/右に左/右の部分があります」を混同し、「一致した行」と「すべて」を使用して、他のテーブルの行とnullによって拡張された行を意味します。
philipxy

104

内部結合は、結合の反対側(右側)に一致するレコードがある場合にのみ行を表示します。

(左側の)外部結合では、結合の反対側(右側)に一致する行がない場合でも、左側に各レコードの行が表示されます。一致する行がない場合、反対側(右側)の列にはNULLが表示されます。


82

内部結合では、関連するIDを持つレコードが結合テーブルに存在する必要があります。

外部結合は、右側に何も存在しない場合でも、左側のレコードを返します。

たとえば、OrdersテーブルとOrderDetailsテーブルがあります。それらは「OrderID」によって関連付けられています。

注文

  • OrderID
  • 顧客名

注文詳細

  • OrderDetailID
  • OrderID
  • 商品名
  • 数量
  • 価格

リクエスト

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

OrderDetailsテーブルに何かがあるOrderのみを返します。

OUTER LEFT JOINに変更した場合

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

次に、OrderDetailsレコードがない場合でも、Ordersテーブルからレコードを返します。

これを使用して、次のようなwhere句を追加することで、孤立した注文の可能性を示すOrderDetailsがない注文を見つけることができますWHERE OrderDetails.OrderID IS NULL


1
シンプルでありながら現実的な例に感謝します。リクエストSELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASCSELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC(MySQL)に変更し、成功しました。追加の条件についてはよく
わかり

68

簡単な言葉で:

内部結合 ->親テーブルと子テーブルから共通のレコードのみを取得します。親テーブルの主キーが子テーブルの外部キーと一致します。

左結合 ->

疑似コード

1.Take All records from left Table
2.for(each record in right table,) {
    if(Records from left & right table matching on primary & foreign key){
       use their values as it is as result of join at the right side for 2nd table.
    } else {
       put value NULL values in that particular record as result of join at the right side for 2nd table.
    }
  }

右結合:左結合の正反対。右結合の右側のLEFT JOINにテーブルの名前を入力すると、LEFT JOINと同じ出力が得られます。

外部結合:両方のテーブルのすべてのレコードを表示しますNo matter what。左のテーブルのレコードが、主キー、外部キーに基づいて右のテーブルと一致しない場合は、結合の結果としてNULL値を使用します。

例:

例

2つのテーブルについて今仮定しましょう

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

ここでは、employeesテーブルはマスターテーブル、phone_numbers_employeesは子テーブルです(子テーブルemp_idに接続employee.idする外部キーとして含まれています)。

内部結合

従業員テーブルの主キー(ID)が子テーブルの外部キーPhone_numbers_employees(emp_id)と一致する場合のみ、2つのテーブルのレコードを取得します。

したがって、クエリは次のようになります。

SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

ここでは、上記で説明したように、主キー=外部キーで一致する行のみを取得します。主キー=外部キーで一致しない行は、結合の結果としてスキップされます。

左結合

左結合は、右のテーブルに一致する行があるかどうかに関係なく、左のテーブルのすべての行を保持します。

SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

外部結合

SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

概略的には次のようになります。

図


4
結果は、主キー/一意キー/候補キーおよび外部キーとは(それ自体は)何もしません。行動は、それらを参照することなく説明できます。クロス結合が計算され、ON条件に一致しない行は除外されます。さらに、外部結合の場合、フィルタリングされた行/
一致し

SQL結合が常に主キー/外部キーの一致であるという前提が、このベン図の誤用を引き起こしています。それに応じて回答を修正してください。
Colm Bhandal

58

を使用INNER JOINして、一致する両方のテーブルからすべての行を返します。つまり、結果のテーブルでは、すべての行と列に値があります。

OUTER JOIN得られたテーブル空の列を有していてもよいです。外部結合はまたはのいずれLEFTRIGHTです。

LEFT OUTER JOIN 2番目のテーブルに一致がない場合でも、最初のテーブルからすべての行を返します。

RIGHT OUTER JOIN 最初のテーブルに一致がない場合でも、2番目のテーブルのすべての行を返します。



54

INNER JOIN2つのテーブルを比較する場合、少なくとも一致する必要があります。たとえば、A ٨ B(A交差B)を意味するテーブルAとテーブルB。

LEFT OUTER JOIN そして LEFT JOIN同じです。両方のテーブルで一致するすべてのレコードと、左側のテーブルのすべての可能性が提供されます。

同様に、RIGHT OUTER JOINRIGHT JOIN同じです。両方のテーブルで一致するすべてのレコードと、適切なテーブルのすべての可能性が提供されます。

FULL JOIN組み合わせですLEFT OUTER JOINRIGHT OUTER JOIN重複せず。


43

答えはそれぞれの意味であり、結果でも同じです。

注:
ではSQLite何もありませんRIGHT OUTER JOINFULL OUTER JOIN
そしてまたMySQLありませんFULL OUTER JOIN

私の答えは上記のメモに基づいています。

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

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTER JOIN:次のように
CROSS JOINまたは次の,ようにして、これらすべてのテーブルデータを保持できます。

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

INNER JOIN:使用できる
ような関係に基づいて、上記の結果にフィルターを追加するtable1.id = table2.id場合INNER JOIN

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

LEFT [OUTER] JOIN:
上記の結果の1つのテーブルのすべての行が同じリレーションで必要な場合LEFT JOIN
RIGHT JOINの場合はテーブルの場所を変更するだけです)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

FULL OUTER JOIN:
結果に他のテーブルのすべての行も含めたい場合は、以下を使用できますFULL OUTER JOIN

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

まあ、あなたのニーズとして、あなたはあなたのニーズをカバーするものをそれぞれ選択します;)


full outer joinMySQL にはないことをメモに追加できます。
potashin

35

インナージョイン。

結合とは、2つのテーブルの行を結合することです。インナーには参加しますクエリで指定した基準に基づいて2つのテーブルを一致させる試みを、そして唯一のその試合の行を返します。結合の最初のテーブルの行が2番目のテーブルの2つの行と一致する場合、結果には2つの行が返されます。最初のテーブルの行が2番目のテーブルの行と一致しない場合、その行は返されません。同様に、最初の行と一致しない行が2番目のテーブルにある場合、その行は返されません。

外部結合。

Aは、ジョイン、左第二テーブルの行に最初のテーブルからの行の一致を見つけるための試み。一致が見つからない場合は、最初のテーブルの列を返し、2番目のテーブルの列は空白(null)のままにします。


28

ここに画像の説明を入力してください

  • INNER JOIN2つ以上のテーブルの最も一般的な結合。テーブルONの主キーとforignkeyリレーションの両方で一致したデータを返します。
  • OUTER JOINと同じですがINNER JOINNULLResultSetのデータも含まれます。
    • LEFT JOIN= INNER JOIN+ 左のテーブルのNull一致しないデータと右のテーブルの一致。
    • RIGHT JOIN= INNER JOIN+ 左のテーブルと一致する右のテーブルのNull一致しないデータ。
    • FULL JOIN= INNER JOIN+ テーブルと左テーブルの両方で一致する不一致データNull
  • テーブルがそれ自体でデータを参照する場合、自己結合はSQLのキーワードではなく、自己結合と呼ばれます。を使用してINNER JOINOUTER JOIN自己結合クエリを記述できます。

例えば:

SELECT * 
FROM   tablea a 
       INNER JOIN tableb b 
               ON a.primary_key = b.foreign_key 
       INNER JOIN tablec c 
               ON b.primary_key = c.foreign_key 

27

他の回答では、パフォーマンスとオプティマイザに関する詳細はあまりわかりません。

時々それだけを知っておくのは良いことです INNER JOIN連想的であるということです。つまり、オプティマイザはそれを操作するための最も多くのオプションを持っています。結合順序を並べ替えて、同じ結果をより速く保持できます。オプティマイザは、ほとんどの結合モードを使用できます。

一般的INNER JOINに、異なる種類の結合の代わりに使用することをお勧めします。(もちろん、予想される結果セットを考慮して可能であれば)

この奇妙な連想的な振る舞いについて、良い例と説明がいくつかあります:


4
あるタイプの結合を別のタイプの結合に使用することは、おそらく「良い習慣」ではありません。使用する結合によって、必要なデータが決まります。別のものを使用すると、誤りになります。さらに、Oracleでは、少なくともこの答えは完全に間違っています。それはすべてにとって完全に間違っているように聞こえ、あなたには証拠がありません。証拠はありますか?
Ben

1. 使ってみるという意味です。LEFT OUTERの参加を利用している多くの人が、理由もなくどこでも参加しているのを見ました。(結合された列は 'nullではありませんでした。')これらの場合、INNER結合を使用するほうが確実に良いでしょう。2.関連付けられていない動作を説明するリンクを、私が説明するよりもよく追加しました。
Lajos Veres 14

私が知ってINNER JOINいるようにLEFT JOIN、ほとんどの場合よりも遅く、そして人々は予期しない結果を削除するためLEFT JOININNER JOINを追加する代わりに使用できます;)WHERENULL
shA.t

これらのコメントは私を少し不確かなものにしました。なぜINNER遅いと思いますか?
Lajos Veres

エンジンに依存します。gnu join、joinkeys、DB2、MySQL。緩いタイピングや明示的なキャストなどのパフォーマンストラップがたくさんあります。
mckenzm

26

非常に愛されている赤い陰影のベン図を批判したので、私は自分の試みを投稿するのは公正だと思いました。

@マーティン・スミスの答えは長い間この束の中で最高ですが、彼は各テーブルのキー列のみを表示していますが、理想的には非キー列も表示する必要があると思います。

許可された30分でできる最善のことですが、キー値が存在しないためにnullが存在すること、TableBまたはOUTER JOIN実際には結合ではなく結合であることがnullが適切に示されているとはまだ思いません。

ここに画像の説明を入力してください


2
質問は、INNER結合とOUTER結合の違いを求めていますが、必ずしも左外部結合ではありませんlol
LearnByReading

@LearnByReading:右の私の絵は右外であるつまり置き換えジョインTableA a LEFT OUTER JOIN TableB bTableB B RIGHT OUTER JOIN TableA a
onedaywhen

26

以下のための正確なアルゴリズムはINNER JOINLEFT/RIGHT OUTER JOIN次のとおりです。

  1. 最初のテーブルから各行を取得します。 a
  2. その隣の2番目のテーブルのすべての行を検討します。 (a, b[i])
  3. ON ...各ペアに対して句を評価します。ON( a, b[i] ) = true/false?
    • 条件がに評価されるとtrue、その結合された行を返し (a, b[i])ます。
    • 一致せずに2番目のテーブルの最後に到達すると、これはOuter Join次に、他のテーブルのすべての列に使用する(仮想)ペアを返しNullます:(a, Null)LEFT外部結合または(Null, b)RIGHT外部結合。これは、最初のテーブルのすべての行が最終結果に確実に存在するようにするためです。

注:ON句で指定する条件は何でもかまいません。主キーを使用する必要はありません(両方のテーブルの列を常に参照する必要はありません)。例えば:

内部結合と左外部結合


ここに画像の説明を入力してください

注:左結合=左外部結合、右結合=右外部結合。


20

最も単純な定義

内部結合:両方のテーブルから一致したレコードを返します。

完全外部結合:戻り値に一致し、一致しないレコードから一致しないレコードの場合はnullとの両方のテーブルから両方のテーブルを

左外部結合:戻り値に一致し、一致しないレコードのみのテーブルから左側

右外部結合:一致したレコードと一致しないレコードを、右側のテーブルからのみ返します。

要するに

一致+左不一致+右不一致= 完全外部結合

一致+左不一致=左外部結合

一致+右不一致=右外部結合

一致= 内部結合


1
これはすばらしいことであり、結合が時系列インデックスに対して期待どおりに機能しない理由を説明しています。1秒間隔のタイムスタンプは無比です。
yeliabsalohcin 2017

1
@yeliabsalohcin質問に対するコメントでは、「期待どおり」または「機能」については説明しません。それはあなたが不思議に他の人に期待するいくつかの説明できない個人的な誤解です。ここで書いているときのように、読んでいるとき(明確な文章を誤って解釈したり、不明瞭な文章を受け入れたりしているとき)に単語をだらしなく扱うと、誤解が生じる可能性があります。実際、ここでのほとんどのようなこの答えは不明確で間違っています。「内部結合:両方のテーブルから一致したレコードを返す」は、入力列セットが異なる場合に間違っています。あることを言おうとしていますが、そうではありません。(私の答えを参照してください。)
philipxy

9

簡単な言葉で、

1. INNER JOINまたはEQUI JOIN:両方のテーブルの条件のみに一致する結果セットを返します。

2. OUTER JOIN:条件が一致するかどうかにかかわらず、両方のテーブルのすべての値の結果セットを返します。

3. LEFT JOIN:左のテーブルのすべての値の結果セットと、右のテーブルの条件に一致する行のみを返します。

4. RIGHT JOIN:右のテーブルのすべての値の結果セットと、左のテーブルの条件に一致する行のみを返します。

5. FULL JOIN:完全結合と完全外部結合は同じです。


5

SQLには主に2つのタイプのJOINがあります:[INNERおよびOUTER]


次のような2つのテーブルがあり、それぞれ1つの列とデータがあるとします。

A    B
-    -
1    3
2    4
3    5
4    6
7
8

(1,2,7,8)はAに固有であり、(3,4)は共通であり、(5,6)はBに固有であることに注意してください。



  • (INNER)JOIN

INNER JOINキーワードは、条件が満たされている限り、両方のテーブルからすべての行を選択します。このキーワードは、条件が満たされる両方のテーブルのすべての行を組み合わせて結果セットを作成します。つまり、共通フィールドの値は同じになります。

内部結合

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

結果:

a | b
--+--
3 | 3
4 | 4


  • LEFT(OUTER)JOIN

この結合は、結合の左側にあるテーブルのすべての行と、結合の右側にあるテーブルに一致する行を返します。右側に一致する行がない行。結果セットにはnullが含まれます。LEFT JOINはとしても知られていLEFT OUTER JOINます。

LEFT JOIN / LEFT OUTER JOIN

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

結果:

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4
7 | null
8 | null


  • RIGHT(OUTER)JOIN:右側のテーブルからすべてのレコードを返し、左側のテーブルから一致したレコードを返します

RIGHT JOIN / RIGHT OUTER JOIN

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

結果:

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6


  • FULL(OUTER)JOIN

    FULL JOINは、LEFT JOINとRIGHT JOINの両方の結果を組み合わせて結果セットを作成します。結果セットには、両方のテーブルのすべての行が含まれます。一致する行がない場合、結果セットにはNULL値が含まれます。

FULL JOIN / FULL OUTER JOIN

select * from a FULL OUTER JOIN b on a.a = b.b;

結果:

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5
   7 | null
   8 | null

1
ベン図は、一般的な場合のSQL結合を説明するのに十分ではありません。SQL結合は、テーブル間の行を必ずしも1対1で一致させる必要はありません。たとえば、外部キーと主キーを使用します。
Colm Bhandal

行が一致しない2つのテーブルをどのように結合しますか?結合を実行するには、列の主キーまたは外部キー、またはいくつかの共通フィールドが必要です。なぜこの回答に反対票を投じたのでしょうか。ベン図は、SQL JOINがどのように機能するかを説明するソースです。結合を表すより良い例はありますか?そうでない場合は、賛成してください。そうすれば、人々はより良​​い解決策を得られます。ありがとうございました。
Mayur

あなたは図を投稿に入れています。図の凡例は何ですか?-各セットの要素は何ですか?そして、テーブルがバッグではなくセットであるという事実はどうですか?あなたは言わない。それらがセットではないことの1つは、ラベルごとのAおよびBの行です。このページの投稿に対する私のコメントを参照してください。この投稿は、他の場所で見られる間違った使用法を盲目的に繰り返していますが、理解も質問もされていません。また、あなたがここでテキストで言うことは不明確で間違っています。また、すでにここにある多くの答えには何も追加されません。(ほとんどすべてがかなり貧弱ですが。)PSコメントではなく、編集によって明確にしてください。
philipxy

結合やクエリにはFKは必要ありません。列を含む任意の条件で、制約、トリガー、アサーションに関係なく、任意の2つのテーブルを結合できます。
philipxy

3
  • 内部結合 - 同等のクエリのいずれかを使用した内部結合は、2つのテーブルの共通部分、つまり、それらが共通に持つ2つの行を提供します。

  • 左外部結合 - 左外部結合は、Aのすべての行に加えて、Bのすべての共通行を提供します。

  • 完全外部結合 - 完全外部結合は、AとBの和、つまり、Aのすべての行とBのすべての行を結合します。Aの何かに対応するデータがBにない場合、Bの部分はnull、およびその逆


1
これは間違っていて不明確です。テーブルに同じ列がない限り、結合は交差ではありません。外部結合には同じ列がない限り、AまたはBからの行はありません。その場合、NULLは追加されません。あなたは何かを言おうとしていますが、あなたはそれを言っていません。あなたは正しくまたは明確に説明していません。
philipxy 2017

@philipxy:ステートメントに同意Join is not an intersection unless the tables have the same columnsできません。必要な列を結合できます。値が一致すると、それらの列が結合されます。
SuicideSheep 2017

そのコメントはあなたの答えと同じくらい不明確です。(たとえば、結果の共通列のサブ行値のセットは、各入力の共通列のサブ行値のセットの共通部分ですが、それはあなたが書いたものではありません。明確ではありません。)
philipxy 2017

私が意味したのは、同じ列を持つ入力の自然な内部結合である場合、結合は入力の交差のみであるということです。「交差点」および「結合」という単語を誤って使用しています。
philipxy

3

1. 内部結合:結合とも呼ばれます。一致する場合にのみ、左のテーブルと右のテーブルの両方に存在する行を返します。それ以外の場合は、ゼロのレコードを返します。

例:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

出力1

2. 完全外部結合:完全結合とも呼ばれます。左テーブルと右テーブルの両方に存在するすべての行を返します。

例:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

出力2

3. 左外部結合:または単に左結合と呼ばれます。これは、左のテーブルに存在するすべての行と、右のテーブル(存在する場合)の一致する行を返します。

4. 右外部結合:右結合とも呼ばれます。左側のテーブル(存在する場合)から一致する行と、右側のテーブルに存在するすべての行を返します。

参加する

結合の利点

  1. より速く実行します。

2
これは、テーブルに同じ列セットがある場合にのみ正しいです。(内部結合と交差および完全結合と結合を混同します。)また、「一致」は未定義です。私の他のコメントを読んでください。
philipxy 2017

2

以下の2つのテーブルを検討してください。

EMP

empid   name    dept_id salary
1       Rob     1       100
2       Mark    1       300
3       John    2       100
4       Mary    2       300
5       Bill    3       700
6       Jose    6       400

部門

deptid  name
1       IT
2       Accounts
3       Security
4       HR
5       R&D

内部結合:

ほとんどの場合、SQLクエリでは単なるJOINとして記述されます。テーブル間で一致するレコードのみを返します。

すべての従業員とその部門名を調べます。

Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security

上記のように、dept_id はDepartmentテーブルで一致するものを見つけられないため、EMPJoseから出力に出力されません。同様に、行はから印刷されません6HRR&D Empテーブルで一致が見つからなかったため、Departmentテーブルません。

したがって、INNER JOINまたは単にJOINは、一致する行のみを返します。

LEFT JOIN:

これは、LEFTテーブルのすべてのレコードと、RIGHTテーブルの一致するレコードのみを返します。

Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security
6       Jose    

したがって、上記の出力を確認すると、LEFTテーブル(Emp)のすべてのレコードが、RIGHTテーブルの一致するレコードだけで印刷されます。

HRそしてR&D行から印刷されていない部門の彼らはDEPT_ID上のEMP表の一致が見つからなかったとしてテーブル。

したがって、LEFT JOINは、左テーブルのすべての行と、右テーブルの一致する行のみを返します。

ここでデモを確認することもできます


2

一般的なアイデア

参照してください答えをすることによってマーティン・スミスを含め、特に間の違いより良いillustationsと異なる加入の説明のためにFULL OUTER JOINRIGHT OUTER JOINLEFT OUTER JOIN

これら2つの表は、JOIN以下のsの表現の基礎を形成します。

基礎

CROSS JOIN

CrossJoin

SELECT *
  FROM citizen
 CROSS JOIN postalcode

結果は、すべての組み合わせのデカルト積になります。JOIN条件は必要ありません:

CrossJoinResult

内部結合

INNER JOIN 単純に同じです: JOIN

InnerJoin

SELECT *
  FROM citizen    c
  JOIN postalcode p ON c.postal = p.postal

結果は、必要なJOIN条件を満たす組み合わせになります。

InnerJoinResult

左外部結合

LEFT OUTER JOIN と同じです LEFT JOIN

LeftJoin

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal

結果citizenは、に一致するものがなくても、すべてのものになりますpostalcode。ここでもJOIN条件が必要です。

LeftJoinResult

再生用データ

すべての例はOracle 18cで実行されています。テーブルのスクリーンショットの元でもあるdbfiddle.ukから入手できます。

CREATE TABLE citizen (id      NUMBER,
                      name    VARCHAR2(20),
                      postal  NUMBER,  -- <-- could do with a redesign to postalcode.id instead.
                      leader  NUMBER);

CREATE TABLE postalcode (id      NUMBER,
                         postal  NUMBER,
                         city    VARCHAR2(20),
                         area    VARCHAR2(20));

INSERT INTO citizen (id, name, postal, leader)
              SELECT 1, 'Smith', 2200,  null FROM DUAL
        UNION SELECT 2, 'Green', 31006, 1    FROM DUAL
        UNION SELECT 3, 'Jensen', 623,  1    FROM DUAL;

INSERT INTO postalcode (id, postal, city, area)
                 SELECT 1, 2200,     'BigCity',         'Geancy'  FROM DUAL
           UNION SELECT 2, 31006,    'SmallTown',       'Snizkim' FROM DUAL
           UNION SELECT 3, 31006,    'Settlement',      'Moon'    FROM DUAL  -- <-- Uuh-uhh.
           UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space'   FROM DUAL;

JOINと遊ぶときの境界がぼやけるWHERE

CROSS JOIN

CROSS JOIN結果として、The General Idea /として行が生成されますINNER JOIN

SELECT *
  FROM citizen          c
  CROSS JOIN postalcode p
 WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows

を使用CROSS JOINして結果を取得LEFT OUTER JOINするには、NULL行を追加するなどのトリックが必要です。省略されています。

内部結合

INNER JOINデカルト積になります。一般的なアイデアと同じCROSS JOINです:

SELECT *
  FROM citizen    c
  JOIN postalcode p ON 1 = 1  -- < -- The ON condition makes it a CROSS JOIN

これは、内部結合が、条件に一致しない結果が削除されたクロス結合として実際に見られる場所です。ここでは、結果の行は削除されません。

INNER JOINの結果を取得するために使用するには、LEFT OUTER JOINトリックも必要です。省略されています。

左外部結合

LEFT JOIN結果は、The General Idea /として行に表示されますCROSS JOIN

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN

LEFT JOIN結果は、The General Idea /として行に表示されますINNER JOIN

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal
 WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode

ベン図のトラブル

「sql join cross inner outer」での画像インターネット検索では、多数のベン図が表示されます。私は以前、机の上に印刷したものを持っていました。しかし、表現には問題があります。

ベン図は、要素が一方または両方のセットに含まれる場合があるセット理論に最適です。しかし、データベースの場合、1つの "セット"内の要素は、テーブルの行のように見えるため、他のテーブルにも存在しないように見えます。複数のテーブルに1つの行が存在するようなものはありません。行はテーブルに固有です。

自己結合は、各要素が両方のセットで実際に同じであるコーナーケースです。しかし、それでも以下の問題が解決するわけではありません。

以下の説明でAは、セットは左側のセット(citizen表)を表し、セットBは右側のセット(postalcode表)です。

CROSS JOIN

両方のセット内のすべての要素は、私たちに必要な意味、他のセット内のすべての要素と一致しているAすべての量Bの元素とB、すべての量Aを適切このデカルト積を表すための要素。セット理論は、セット内の複数の同一要素に対して作成されていないため、ベン図を適切に表すと実用的でない/不可能であることがわかります。全然合わないようですUNION

行は異なります。UNION合計で7行です。ただし、一般的なSQL結果セットとの互換性はありません。そして、これはaがどのようにCROSS JOIN機能するかではありません:

CrossJoinUnion1

このように表現しようとすると:

CrossJoinUnion2Crossing

..しかし、今はそれのように見えますが、INTERSECTION確かにそうではありません。さらに、INTERSECTION実際には2つの異なるセットのいずれにもある要素はありません。ただし、次のような検索可能な結果に非常に似ています。

CrossJoinUnionUnion3

参考までに、CROSS JOINsの1つの検索可能な結果は、Tutorialgatewayにあります。のINTERSECTIONように、空です。

内部結合

要素の値はJOIN条件によって異なります。これは、すべての行がその条件に固有になるという条件の下で表すことができます。意味id=x1つの行にのみ当てはまります。テーブルAcitizen)の行が条件の下でテーブルBpostalcode)の複数の行と一致するJOINと、結果には次の問題と同じ問題が発生CROSS JOINします。一意性の条件の下では、図は機能しますが、JOIN条件が図内の要素の配置を決定することを覚えておいてください。JOIN残りの行の乗車について、状態の値のみを確認します。

InnerJoinIntersection-塗りつぶし

この表現はINNER JOINON 1 = 1条件付きでを使用すると、完全にバラバラになりCROSS JOINます。

自己とJOIN、行は、実際には、両方のテーブルにidential要素であるが、両方としてテーブルを表すAB非常に適していません。たとえば、ある要素をBの別の要素と一致さJOINせる一般的な自己条件はでありA別の要素でON A.parent = B.childfromからAto Bに一致します。SQLこのような例から:

SELECT *
  FROM citizen c1
  JOIN citizen c2 ON c1.id = c2.leader

SelfJoinResult

つまり、スミスはグリーンとジェンセンの両方のリーダーです。

外部結合

この場合も、1つの行に他のテーブルの行と複数の一致がある場合に問題が発生します。OUTER JOIN空のセットと一致するようにできるので、これはさらに複雑です。しかし、セット理論では、任意のセットCと空のセットの結合は常にちょうどCです。空のセットは何も追加しません。これの表現LEFT OUTER JOINは通常、AからAの一致があるかどうかに関係なく、の行が選択されていることを示すためにすべてを表示しているだけBです。「一致する要素」には、上の図と同じ問題があります。彼らは状態に依存します。そして、空のセットは次のようにさまよっているようAです:

LeftJoinIntersection-塗りつぶし

WHERE句-意味をなす

CROSS JOIN月のスミスと郵便番号でaからすべての行を検索します。

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   AND p.area = 'Moon';

どこ-結果

現在、ベン図はを反映するために使用されていませんJOIN。これは句にのみ使用されWHEREます。

どこ

..そしてそれは理にかなっています。

INTERSECTとUNIONが意味をなす場合

交差する

説明されているように、INNER JOIN実際にはありませんINTERSECT。ただし、INTERSECTsは個別のクエリの結果に使用できます。ここで、ベン図は意味があります。別々のクエリからの要素は、実際には、結果の一方または両方に属する行であるためです。Intersectは、明らかに両方のクエリに行が存在する場合にのみ結果を返します。これSQLにより、上記と同じ行が作成されWHERE、ベン図も同じになります。

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
INTERSECT
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

連合

アンはOUTER JOINありませんUNION。ただしUNION、と同じ条件で作業すると、INTERSECT両方SELECTのを組み合わせたすべての結果が返されます。

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
UNION
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

これは次と同等です:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   OR p.area = 'Moon';

..そして結果を与える:

ユニオン-結果

また、ここではベン図が理にかなっています:

連合

該当しない場合

重要な注意点は、 2つのSELECTの結果からの構造を比較または共用を可能にする、同一である場合、これらの唯一の作品ということです。これら2つの結果では、次のことはできません。

SELECT *
  FROM citizen
 WHERE name = 'Smith'
SELECT *
  FROM postalcode
 WHERE area = 'Moon';

..結果を結合しようとするとUNION

ORA-01790: expression must have same datatype as corresponding expression

さらに興味がある場合は、「ベンのダイアグラムにJOINsql結合を説明するときはベンのダイアグラムにNOと言ってくださいをお読みください。どちらもカバーしていEXCEPTます。


1

非常に正確な関係代数の例を使用して、多くの良い答えがあります。これは、SQLコーディングのジレンマを持つアマチュアまたは初心者のコーダーに役立つ可能性がある非常に簡略化された回答です。

基本的に、多くの場合、クエリJOINは2つのケースにまとめられます。

以下のためのSELECTデータのサブセットA

  • 使用INNER JOIN関連データBあなたが探している必要がありますデータベースの設計ごとに存在します。
  • 使用LEFT JOIN関連データB、あなたが探しているMIGHTMIGHTはありませんが、データベースの設計ごとに存在します。

1

違いinner joinとはouter join以下の通りです:

  1. Inner joinは、一致するタプルに基づいてテーブルを結合した結合ですが、一致したタプルとouter join一致しないタプルの両方に基づいて結合したテーブルです。
  2. Inner join一致しない行が省略されている2つのテーブルの一致する行をマージしますが、2つのテーブルの行をマージし、一致しない行はouter joinnull値で埋められます。
  3. Inner joinは交差演算のouter joinようですが、和演算のようです。
  4. Inner joinは2つのタイプですが、outer join3つのタイプです。
  5. outer joinよりも速いですinner join

1
外部結合の結果は内部結合と同じですが、いくつかの行が追加されているため、外部結合の方が速いと思う理由がわかりません。また、これらの「2種類」の内部結合とは何ですか?私はあなたがアウターについてフル、左、そして右を参照していると思いますか?
マーティン・スミス

1
@ M.achaibou不要なフォーマット変更を行うような編集は行わないでください。演算子の名前は、コードで使用されていない限り、コードではありません。投稿の意味を変更しないでください。投稿者にコメントを投稿してください。担当者がいない場合は、担当者までお待ちください。投稿者がこれを承認したことがありますが、そのような編集は行わないでください。PS外部結合は内部結合より高速ではありません。
philipxy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.