MySQL:結合のタイプの簡単な内訳


157

MySQL結合のタイプの簡単な内訳をお願いします。私はこれらを知っていますが、残りは何を意味するのかわかりません。

  • コンマ区切り(正確にはこれは何の略ですか?):SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • bに一致がない場合でも、aからの情報を表示します。 SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...

他の結合を見たことがありますが、それらがどのように違うのか、INNER/ OUTERとは何か、追加LEFTによって変更が行われることを知りたいです。

結合のしくみはすでに知っています。他の種類の結合があるかどうか、または同じ結果を得る方法が異なるかどうかだけを知りたいです。


これはあなたの質問に答えますか?「INNER JOIN」と「OUTER JOIN」の違いは何ですか?
philipxy

回答:


463

3
+1が両方ともcross joinありません。これはデカルト積を行います。
Denis de Bernardy

11
@denis:codinghorror.comリンクを詳しく見てください:There's also a cartesian product or cross join, which as far as I can tell, can't be expressed as a Venn diagram:
Rufinus

1
この図を印刷して、自分のオフィスの壁に貼り付けていることに驚いています。あなたは私の人生を変えた!
yossico 2014年

41
問題は特にMySQLについてです。MySQLはFULL OUTER結合をサポートしていません。
Mike Baranczak 2014年

4
そしてもちろん、これがこのグラフを投稿しない理由になるはずです。ため息
ルフィナス2014年

27

あなたのコメントに基づいて、それぞれの簡単な定義はW3Schoolsで最もよく見つかります 。各タイプの最初の行は、結合タイプの簡単な説明を示します

  • JOIN:両方のテーブルに少なくとも1つの一致がある場合に行を返します
  • LEFT JOIN:右のテーブルに一致がない場合でも、左のテーブルからすべての行を返します
  • RIGHT JOIN:左側のテーブルに一致がない場合でも、右側のテーブルからすべての行を返します
  • FULL JOIN:いずれかのテーブルに一致がある場合に行を返します

編集を終了

一言で言えば、あなたが与えたカンマ区切りの例

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

テーブルをコンマで区切ってテーブルaとbからすべてのレコードを選択しています。これは次のような列でも使用できます

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

次に、例のb.id列とa.beeId列が一致する行の指示された情報を取得します。したがって、例では、b.idがa.beeIdと等しいテーブルaおよびbからすべての情報を取得します。私の例では、b.idがa.beeIdと等しい場合、bテーブルからすべての情報を取得し、a.beeName列からのみ情報を取得します。AND句もあることに注意してください。これは結果を絞り込むのに役立ちます。

mySQL結合と左結合に関する簡単なチュートリアルと説明については、TizagのmySQLチュートリアルをご覧ください。非常に優れた結合の詳細については、Keith J. BrownのWebサイトを確認することもできます。

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


私はすでにすべてを知っています。実際にある種類の結合を探していました。申し訳ありませんが、私の知っていることがはっきりしていません。しかし、簡単な要約を得るためだけに長いドキュメントを探していませんでした。
ブライアンフィールド

答えの別の参照...あなたが仲間にしたいものの多くかもしれません。
Ryan

その編集の+1。一部の人々がそうであるように、私はW3Schoolに対して偏っていません。おそらく私は悪い面をあまり見ていなかったのかもしれませんし、多分それは単なる「聖戦」なのでしょう。また、W3Schoolsのコンテンツを編集しましたので、よろしくお願いしますが、自由に編集してください。受け入れられた回答のビジュアルはすべてすばらしいですが、一部は実際にはまったく同じ結合のバリエーションです。これは良い代替案です。
ブライアンフィールド

ありがとうジョージ、編集が正しいことを言ってもまったく問題ありません!私は、人々が彼らにとって適切な情報源、多かれ少なかれ情報、たくさんの例を見つけるか、どれも見つけない必要があると信じています。W3Schoolは正確で簡潔であり、良い例もある傾向があります。Tizagも同様です。簡単に交わす
Ryan

1
mysqlにはFULL JOINがないため、これらのリンクはあまり役に立ちません。
2013年

13

次のような2つのテーブルがあります。

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+

> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER JOINは両方のテーブルを処理します

INNER JOINは両方のテーブルを処理するため、両方のテーブルに1つしかない場合にのみ行が取得されます。一致するペアが複数ある場合は、複数の行が表示されます。

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

順序を逆にしても、INNER JOINに違いはありません。これは、両方のテーブルが考慮されるためです。

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

同じ行を取得しますが、列の順序は異なります。これは、表の順序が異なるためです。

LEFT JOINは最初のテーブルのみを考慮します

LEFT JOINは指定した最初のテーブルを考慮し、2番目のテーブルはあまり考慮しないため、2番目に対応する行がない場合でも、常に最初のテーブルから行を取得します。

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

上記では、table_aのすべての行が表示されますが、それらの一部はテーブルbのどの行とも一致しませんが、table_bのすべての行ではなく、table_aの何かと一致する行のみが表示されます。

テーブルの順序を逆にすると、LEFT JOINの動作が異なります。

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

これで、table_bのすべての行が取得されますが、table_aの一致する行のみが取得されます。

RIGHT JOINは2番目のテーブルのみを考慮します

a RIGHT JOIN bとまったく同じ行を取得しますb LEFT JOIN a。唯一の違いは、列のデフォルトの順序です。

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

これは、table_b LEFT JOIN table_aLEFT JOINセクションで見たと同じ行です。

同様に:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

と同じ行table_a LEFT JOIN table_bです。

まったく参加しないため、すべてのコピーが得られます

結合句なし:コンマで区切られたJOIN句をまったく使用せずにテーブルを書き込む場合、可能なすべての組み合わせで、2番目のテーブルのすべての行の隣に最初のテーブルのすべての行が書き込まれます。

> SELECT * FROM table_b, table_a;        
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(これは私のブログ投稿SQL結合タイプの例からのものです


@Anu評判が低く、編集内容を他の人にレビューする必要がある場合は、そのような些細な編集を行わないでください。時間を浪費しているだけです。その編集は違いがないとして拒否されるべきでした。変更したコードは実際には間違っていなかったので、コメントできたはずです。
philipxy

@philipxyわかりました。そのことに注意してください。説明を理解しようとしたところ、そのようなタイプミスを見たので、わかりやすくするために編集しました。確かにこれは良い答えであり、私の意図はそれをより正しく保つことでした。
Anu

@Anuこの回答には、ほとんどの回答と同じ断片化された不完全な説明があります。実際には、出力が入力の関数として何であるかは述べていません。また、両方のページで提案されている複製と私のコメントのほぼすべての回答も参照してください。そこで私の答えも参照してください。PS私はちょうどこれを昨日から見直した編集サイズを再確認しました(もちろん、Meta Stack OverflowMeta Stack Exchangeにはさらに多くの関連する投稿があります。)
philipxy

11

完全な外部結合はmysqlに存在しないため、左結合と右結合の組み合わせを使用する必要がある場合があります。

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