また、どのようLEFT JOIN
にRIGHT JOIN
してFULL JOIN
フィットしますか?
また、どのようLEFT JOIN
にRIGHT JOIN
してFULL JOIN
フィットしますか?
回答:
非常に一般的なケースである、重複のない列で結合していると仮定します。
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
ベン図は実際には私にはそれをしません。
たとえば、クロス結合と内部結合の違いは示されていません。より一般的には、さまざまな種類の結合述語の違いが示されていないか、それらがどのように動作するかを推論するためのフレームワークを提供しています。
論理処理を理解するための代替手段はなく、とにかく把握することは比較的簡単です。
on
どこ述語評価さにそれらを維持するステップ1からすべての行に対して句をtrue
(注:実際には、クエリオプティマイザーは上記の純粋に論理的な説明よりも効率的なクエリの実行方法を見つけることができますが、最終結果は同じである必要があります)
まず、完全外部結合のアニメーションバージョンから始めます。さらに説明します。
ソーステーブル
CROSS JOIN
(別名デカルト積)から始めます。これにはありませんON
句、2つのテーブルの行のすべての組み合わせを返すだけです。
クロスジョインBからA.Color、B.Colourを選択します
内部結合と外部結合には、 "ON"句の述語があります。
A.Colour = B.Colourの内部結合BからA.Colour、B.Colourを選択します。
上記は古典的な等価結合です。
内部結合条件は必ずしも等号条件である必要はなく、両方(またはどちらか一方)のテーブルの列を参照する必要はありません。A.Colour NOT IN ('Green','Blue')
クロス結合の各行を評価して戻ります。
1 = 1の内部結合BからA.Colour、B.Colourを選択します。
結合条件は、クロス結合結果のすべての行に対してtrueと評価されるため、これはクロス結合とまったく同じです。16行の画像を再度繰り返すことはありません。
外部結合は、左側のテーブルの行(左側の結合の場合)が右側のテーブルの行とまったく結合しない場合を除いて、内部結合と同じ方法で論理的に評価されNULL
ます。右側の列。
これは単に前の結果を制限して、である行のみを返すようにしますB.Colour IS NULL
。この特定の場合、これらは右側のテーブルで一致しなかったため保持された行であり、クエリはtableで一致しなかった単一の赤い行を返しますB
。これは、反準結合として知られています。
IS NULL
null可能ではないか、結合条件NULL
によってこのパターンが正しく機能し、たまたまそのNULL
値を持つ行が返されないようにするために値が除外されることが保証されているテスト用の列を選択することが重要です一致しない行に加えて列。
右外部結合は、左表の一致しない行を保持し、左側の列をヌル拡張することを除いて、左外部結合と同様に機能します。
完全外部結合は、左と右の結合の動作を組み合わせ、左と右の両方のテーブルから一致しない行を保持します。
クロス結合のどの行も1=0
述部と一致しません。両側のすべての行は、反対側のテーブルの列にNULLを含む通常の外部結合ルールを使用して保持されます。
前のクエリを少し修正するUNION ALL
と、2つのテーブルのうちの1つをシミュレートできます。
WHERE
句(存在する場合)は論理的に結合の後に実行されることに注意してください。よくあるエラーの1つは、左外部結合を実行してから、一致しない行を除外してしまう右テーブルの条件を含むWHERE句を含めることです。上記は最終的に外部結合を実行します...
...そして、「Where」節が実行されます。NULL= 'Green'
はtrueと評価されないため、外部結合によって保持された行は(青色の行とともに)最終的に破棄され、結合が内部の行に効果的に変換されます。
ColorがGreenであるBの行のみを含め、正しい構文に関係なくAのすべての行を含めることが意図されている場合は、次のようになります。
結合は、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
上記の表を使用して、右外部結合の結果セットがどのようになるかを示すことができます。
完全外部結合:- 完全外部結合または完全結合は、結合の結果に一致しない行を含めることで、一致しない情報を保持するために、完全外部結合を使用します。他のテーブルに一致する値があるかどうかに関係なく、両方のテーブルのすべての行が含まれます。
一致した行のみ、つまりを取得します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
簡単な言葉で:
インナーには参加するだけでマッチした行を取得します。
一方、外部結合は、1つのテーブルから一致した行を取得し、他のテーブルのすべての行を取得します。結果は、使用している行によって異なります。
左:右のテーブルの一致した行と左のテーブルのすべての行
右:左のテーブルの一致した行と右のテーブルのすべての行、または
フル:すべてのテーブルのすべての行。一致するかどうかは関係ありません
内部結合では、関連するIDを持つレコードが結合テーブルに存在する必要があります。
外部結合は、右側に何も存在しない場合でも、左側のレコードを返します。
たとえば、OrdersテーブルとOrderDetailsテーブルがあります。それらは「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
。
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 ASC
をSELECT 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)に変更し、成功しました。追加の条件についてはよく
簡単な言葉で:
内部結合 ->親テーブルと子テーブルから共通のレコードのみを取得します。親テーブルの主キーが子テーブルの外部キーと一致します。
左結合 ->
疑似コード
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;
概略的には次のようになります。
INNER JOIN
2つのテーブルを比較する場合、少なくとも一致する必要があります。たとえば、A ٨ B(A交差B)を意味するテーブルAとテーブルB。
LEFT OUTER JOIN
そして LEFT JOIN
同じです。両方のテーブルで一致するすべてのレコードと、左側のテーブルのすべての可能性が提供されます。
同様に、RIGHT OUTER JOIN
とRIGHT JOIN
同じです。両方のテーブルで一致するすべてのレコードと、適切なテーブルのすべての可能性が提供されます。
FULL JOIN
組み合わせですLEFT OUTER JOIN
とRIGHT OUTER JOIN
重複せず。
答えはそれぞれの意味であり、結果でも同じです。
注:
ではSQLite
何もありませんRIGHT OUTER JOIN
かFULL 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 join
MySQL にはないことをメモに追加できます。
インナージョイン。
結合とは、2つのテーブルの行を結合することです。インナーには参加しますクエリで指定した基準に基づいて2つのテーブルを一致させる試みを、そして唯一のその試合の行を返します。結合の最初のテーブルの行が2番目のテーブルの2つの行と一致する場合、結果には2つの行が返されます。最初のテーブルの行が2番目のテーブルの行と一致しない場合、その行は返されません。同様に、最初の行と一致しない行が2番目のテーブルにある場合、その行は返されません。
外部結合。
Aは、ジョイン、左第二テーブルの行に最初のテーブルからの行の一致を見つけるための試み。一致が見つからない場合は、最初のテーブルの列を返し、2番目のテーブルの列は空白(null)のままにします。
INNER JOIN
2つ以上のテーブルの最も一般的な結合。テーブルONの主キーとforignkeyリレーションの両方で一致したデータを返します。OUTER JOIN
と同じですがINNER JOIN
、NULL
ResultSetのデータも含まれます。
LEFT JOIN
= INNER JOIN
+ 左のテーブルのNull
一致しないデータと右のテーブルの一致。RIGHT JOIN
= INNER JOIN
+ 左のテーブルと一致する右のテーブルのNull
一致しないデータ。FULL JOIN
= INNER JOIN
+ 右テーブルと左テーブルの両方で一致する不一致データNull
。INNER JOIN
、OUTER 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
他の回答では、パフォーマンスとオプティマイザに関する詳細はあまりわかりません。
時々それだけを知っておくのは良いことです INNER JOIN
連想的であるということです。つまり、オプティマイザはそれを操作するための最も多くのオプションを持っています。結合順序を並べ替えて、同じ結果をより速く保持できます。オプティマイザは、ほとんどの結合モードを使用できます。
一般的INNER JOIN
に、異なる種類の結合の代わりに使用することをお勧めします。(もちろん、予想される結果セットを考慮して可能であれば)
この奇妙な連想的な振る舞いについて、良い例と説明がいくつかあります:
INNER JOIN
いるようにLEFT JOIN
、ほとんどの場合よりも遅く、そして人々は予期しない結果を削除するためLEFT JOIN
にINNER JOIN
を追加する代わりに使用できます;)WHERE
NULL
INNER
遅いと思いますか?
非常に愛されている赤い陰影のベン図を批判したので、私は自分の試みを投稿するのは公正だと思いました。
@マーティン・スミスの答えは長い間この束の中で最高ですが、彼は各テーブルのキー列のみを表示していますが、理想的には非キー列も表示する必要があると思います。
許可された30分でできる最善のことですが、キー値が存在しないためにnullが存在すること、TableB
またはOUTER JOIN
実際には結合ではなく結合であることがnullが適切に示されているとはまだ思いません。
TableA a LEFT OUTER JOIN TableB b
でTableB B RIGHT OUTER JOIN TableA a
以下のための正確なアルゴリズムはINNER JOIN
、LEFT/RIGHT OUTER JOIN
次のとおりです。
a
(a, b[i])
ON ...
各ペアに対して句を評価します。ON( a, b[i] ) = true/false?
true
、その結合された行を返し (a, b[i])
ます。Outer Join
次に、他のテーブルのすべての列に使用する(仮想)ペアを返しNull
ます:(a, Null)
LEFT外部結合または(Null, b)
RIGHT外部結合。これは、最初のテーブルのすべての行が最終結果に確実に存在するようにするためです。注:ON
句で指定する条件は何でもかまいません。主キーを使用する必要はありません(両方のテーブルの列を常に参照する必要はありません)。例えば:
... ON T1.title = T2.title AND T1.version < T2.version
(=>使用例としてこの投稿を参照:列の最大値を持つ行のみを選択してください)... ON T1.y IS NULL
... ON 1 = 0
(サンプルと同じ)注:左結合=左外部結合、右結合=右外部結合。
最も単純な定義
内部結合:両方のテーブルから一致したレコードを返します。
完全外部結合:戻り値に一致し、一致しないレコードから一致しないレコードの場合はnullとの両方のテーブルから両方のテーブルを。
左外部結合:戻り値に一致し、一致しないレコードのみのテーブルから左側。
右外部結合:一致したレコードと一致しないレコードを、右側のテーブルからのみ返します。
要するに
一致+左不一致+右不一致= 完全外部結合
一致+左不一致=左外部結合
一致+右不一致=右外部結合
一致= 内部結合
例
次のような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キーワードは、条件が満たされている限り、両方のテーブルからすべての行を選択します。このキーワードは、条件が満たされる両方のテーブルのすべての行を組み合わせて結果セットを作成します。つまり、共通フィールドの値は同じになります。
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
この結合は、結合の左側にあるテーブルのすべての行と、結合の右側にあるテーブルに一致する行を返します。右側に一致する行がない行。結果セットにはnullが含まれます。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
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値が含まれます。
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
内部結合 - 同等のクエリのいずれかを使用した内部結合は、2つのテーブルの共通部分、つまり、それらが共通に持つ2つの行を提供します。
左外部結合 - 左外部結合は、Aのすべての行に加えて、Bのすべての共通行を提供します。
完全外部結合 - 完全外部結合は、AとBの和、つまり、Aのすべての行とBのすべての行を結合します。Aの何かに対応するデータがBにない場合、Bの部分はnull、およびその逆
Join is not an intersection unless the tables have the same columns
できません。必要な列を結合できます。値が一致すると、それらの列が結合されます。
1. 内部結合:結合とも呼ばれます。一致する場合にのみ、左のテーブルと右のテーブルの両方に存在する行を返します。それ以外の場合は、ゼロのレコードを返します。
例:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
INNER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
2. 完全外部結合:完全結合とも呼ばれます。左テーブルと右テーブルの両方に存在するすべての行を返します。
例:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
FULL OUTER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
3. 左外部結合:または単に左結合と呼ばれます。これは、左のテーブルに存在するすべての行と、右のテーブル(存在する場合)の一致する行を返します。
4. 右外部結合:右結合とも呼ばれます。左側のテーブル(存在する場合)から一致する行と、右側のテーブルに存在するすべての行を返します。
結合の利点
以下の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
から出力に出力されません。同様に、行はから印刷されません6
HR
R&D
Empテーブルで一致が見つからなかったため、Departmentテーブルません。
したがって、INNER JOINまたは単に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は、左テーブルのすべての行と、右テーブルの一致する行のみを返します。
参照してください答えをすることによってマーティン・スミスを含め、特に間の違いより良いillustationsと異なる加入の説明のためにFULL OUTER JOIN
、RIGHT OUTER JOIN
とLEFT OUTER JOIN
。
これら2つの表は、JOIN
以下のsの表現の基礎を形成します。
SELECT *
FROM citizen
CROSS JOIN postalcode
結果は、すべての組み合わせのデカルト積になります。JOIN
条件は必要ありません:
INNER JOIN
単純に同じです: JOIN
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
結果は、必要なJOIN
条件を満たす組み合わせになります。
LEFT OUTER JOIN
と同じです LEFT JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
結果citizen
は、に一致するものがなくても、すべてのものになりますpostalcode
。ここでもJOIN
条件が必要です。
すべての例は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
結果として、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
表)です。
両方のセット内のすべての要素は、私たちに必要な意味、他のセット内のすべての要素と一致しているA
すべての量B
の元素とB
、すべての量A
を適切このデカルト積を表すための要素。セット理論は、セット内の複数の同一要素に対して作成されていないため、ベン図を適切に表すと実用的でない/不可能であることがわかります。全然合わないようですUNION
。
行は異なります。UNION
合計で7行です。ただし、一般的なSQL
結果セットとの互換性はありません。そして、これはaがどのようにCROSS JOIN
機能するかではありません:
このように表現しようとすると:
..しかし、今はそれのように見えますが、INTERSECTION
確かにそうではありません。さらに、INTERSECTION
実際には2つの異なるセットのいずれにもある要素はありません。ただし、次のような検索可能な結果に非常に似ています。
参考までに、CROSS JOIN
sの1つの検索可能な結果は、Tutorialgatewayにあります。のINTERSECTION
ように、空です。
要素の値はJOIN
条件によって異なります。これは、すべての行がその条件に固有になるという条件の下で表すことができます。意味id=x
は1つの行にのみ当てはまります。テーブルA
(citizen
)の行が条件の下でテーブルB
(postalcode
)の複数の行と一致するJOIN
と、結果には次の問題と同じ問題が発生CROSS JOIN
します。一意性の条件の下では、図は機能しますが、JOIN
条件が図内の要素の配置を決定することを覚えておいてください。JOIN
残りの行の乗車について、状態の値のみを確認します。
この表現はINNER JOIN
、ON 1 = 1
条件付きでを使用すると、完全にバラバラになりCROSS JOIN
ます。
自己とJOIN
、行は、実際には、両方のテーブルにidential要素であるが、両方としてテーブルを表すA
とB
非常に適していません。たとえば、ある要素をBの別の要素と一致さJOIN
せる一般的な自己条件はでありA
、別の要素でON A.parent = B.child
fromからA
to B
に一致します。SQL
このような例から:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
つまり、スミスはグリーンとジェンセンの両方のリーダーです。
この場合も、1つの行に他のテーブルの行と複数の一致がある場合に問題が発生します。OUTER JOIN
空のセットと一致するようにできるので、これはさらに複雑です。しかし、セット理論では、任意のセットC
と空のセットの結合は常にちょうどC
です。空のセットは何も追加しません。これの表現LEFT OUTER JOIN
は通常、A
からA
の一致があるかどうかに関係なく、の行が選択されていることを示すためにすべてを表示しているだけB
です。「一致する要素」には、上の図と同じ問題があります。彼らは状態に依存します。そして、空のセットは次のようにさまよっているようA
です:
CROSS JOIN
月のスミスと郵便番号でaからすべての行を検索します。
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
現在、ベン図はを反映するために使用されていませんJOIN
。これは句にのみ使用されWHERE
ます。
..そしてそれは理にかなっています。
説明されているように、INNER JOIN
実際にはありませんINTERSECT
。ただし、INTERSECT
sは個別のクエリの結果に使用できます。ここで、ベン図は意味があります。別々のクエリからの要素は、実際には、結果の一方または両方に属する行であるためです。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
さらに興味がある場合は、「ベンのダイアグラムにJOINとsql結合を説明するときはベンのダイアグラムにNOと言ってください」をお読みください。どちらもカバーしていEXCEPT
ます。
違いinner join
とはouter join
以下の通りです:
Inner join
は、一致するタプルに基づいてテーブルを結合した結合ですが、一致したタプルとouter join
一致しないタプルの両方に基づいて結合したテーブルです。Inner join
一致しない行が省略されている2つのテーブルの一致する行をマージしますが、2つのテーブルの行をマージし、一致しない行はouter join
null値で埋められます。Inner join
は交差演算のouter join
ようですが、和演算のようです。Inner join
は2つのタイプですが、outer join
3つのタイプです。outer join
よりも速いですinner join
。