質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

1433閲覧

SQL RIGHT JOIN の結合イメージ

Chandler_Bing

総合スコア673

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2020/06/05 13:16

表題の件で質問です。
以下二つのテーブルをRIGHT JOINする際の挙動イメージとそれに関連していくつか質問です。

ユーザー

user_idname
1kento
2shogi
3kenta
4yuki

投稿

idpostuser_id
1HI11
2HI22
3HI33
4HI44
5HI55

以下のSQLを発行します

sql

1 select * from users 2 right join posts 3 on users.id = posts.user_id;

テーブルを結合する際は以下の認識です。

①left join、right joinに関わらずfromの後に書かれたテーブルが結合元(表示結果の左側のテーブル)
【参考】
【INNER JOIN, LEFT JOIN , RIGHT JOIN】テーブル結合の挙動をまとめてみた【SQL】

②結合の挙動は結合元のテーブルのレコードが条件に基づき1レコードずつ結合先のレコードを参照し、条件に合致すれば自分の右にくっつける。
usersテーブルの先頭レコードがpotstテーブルを上から下まで走査し、終了するとusersテーブルの2番目のレコードが同じことを繰り返す。

【inner joinイメージ】
left join時の結合イメージ]

質問

私の認識はあっていますか?


仮に最初に書いたSQL(right join)を発行した場合も
usersテーブルの先頭レコードがpotstテーブルを上から下まで走査し、終了するとusersテーブルの2番目のレコードが同じことを繰り返す。という認識はかわらず、どことも紐づかなかったpotstの最後のレコードを右側に表示するのですよね???

画像で示した矢印もright joinだからといってpostsから引かれる訳ではないですよね(あくまでイメージです。どちらから線を引いても答えは同じですが、、、)

上手く伝わっているか分かりませんが、レベルアップのため、私の考え方が合理的なのか知りたいです。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

構文&結果(仕様)と処理論理(DBごとの実装)は切り離したほうがいいように思います。
ざっくりですが、結合は以下のような結果を返します。(一致前提で)

  • INNER JOINは、左側と右側の両方で一致する行だけが出る。
  • LEFT OUTER JOINは、左側に書いたテーブルの行が全部出る。対応する行がない右側のテーブルの行はNULL。
  • RIGHT OUTER JOINは、右側に書いたテーブルの行が全部出る。対応する行がない左側のテーブルの行はNULL。
  • FULL OUTER JOINは、左側と右側の両方の行が出る。一方に対応する行がなければNULL。
  • 「T1 RIGHT JOIN T2」は「T2 LEFT JOIN T1」と等価。

引用テキスト①left join、right joinに関わらずfromの後に書かれたテーブルが結合元(表示結果の左側のテーブル)

構文的には結合元とか結合先とかは便宜上の呼び方だけで、結合元側を起点として処理するかはデータベースの処理に依存していると思います。
例えば、「T1 RIGHT JOIN T2」と書いても「T2 LEFT JOIN T1」に読み替えてから処理するデータベースもありますし、テーブルの書き順によってデータベースの処理を制御できるとは限りません。

②結合の挙動は結合元のテーブルのレコードが条件に基づき1レコードずつ結合先のレコードを参照し、条件に合致すれば自分の右にくっつける。
usersテーブルの先頭レコードがpotstテーブルを上から下まで走査し、終了するとusersテーブルの2番目のレコードが同じことを繰り返す。

LEFT JOINに読み替えれば理解しやすいと思われます。

結合において結合元/結合先を固定する概念は存在せず、構文に対する処理論理はDB依存であり、結合の構文に対する結果は定められている、といったところでしょうか。

投稿2020/06/06 07:49

etsuhisa

総合スコア416

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

あっているような気もしますが、full outer joinでなければ
leftなら左、rightなら右を基準に合致させて、基準側は
余れば放置、joinする側は余れば削除する・・・感じです

sample

※以下サンプル上げておきます。
書式はmysqlなのでご自身の環境あわせて適宜調整ください

SQL

1create table tbl_left(id int primary key,num int,val int); 2insert into tbl_left values 3(1,1,100), 4(2,1,101), 5(3,2,200), 6(4,2,201), 7(5,3,300); 8 9create table tbl_right(id int primary key,num int,val int); 10insert into tbl_right values 11(11,1,110), 12(12,1,111), 13(13,1,112), 14(14,3,310), 15(15,4,410);

上記に対して以下実行すると

SQL

1select * from tbl_left as l 2left join tbl_right as r 3on l.num=r.num 4order by l.id asc,r.id asc

leftテーブルのidは全て生き、rightテーブルのid=15は削除されています
逆に、以下だと

SQL

1select * from tbl_left as l 2right join tbl_right as r 3on l.num=r.num 4order by l.id asc,r.id asc

leftテーブルのid=3,4は削除され、rightテーブルのidはすべて生きます
ちなみにinner joinすれば

SQL

1select * from tbl_left as l 2inner join tbl_right as r 3on l.num=r.num 4order by l.id asc,r.id asc

行き場のないleftのid=13,14やrightのid=15が削除されます

投稿2020/06/05 13:52

編集2020/06/06 06:18
yambejp

総合スコア116728

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chandler_Bing

2020/06/05 14:19

なるほどそういう感覚ですね。 そうであれば、 >joinする側は余れば削除する これはの質問のsql文(right join)のusersテーブルに当たりますよね????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問