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

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

ただいまの
回答率

88.92%

SQL RIGHT JOIN の結合イメージ

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 240

YutaNkai

score -60

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

ユーザー

user_id name
1 kento
2 shogi
3 kenta
4 yuki

投稿

id post user_id
1 HI1 1
2 HI2 2
3 HI3 3
4 HI4 4
5 HI5 5

以下のSQLを発行します

    select * from users
        right join posts
        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から引かれる訳ではないですよね(あくまでイメージです。どちらから線を引いても答えは同じですが、、、)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

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

sample

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

create table tbl_left(id int primary key,num int,val int);
insert into tbl_left values
(1,1,100),
(2,1,101),
(3,2,200),
(4,2,201),
(5,3,300);

create table tbl_right(id int primary key,num int,val int);
insert into tbl_right values
(11,1,110),
(12,1,111),
(13,1,112),
(14,3,310),
(15,4,410);


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

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


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

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


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

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


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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/05 23:19

    なるほどそういう感覚ですね。
    そうであれば、
    >joinする側は余れば削除する

    これはの質問のsql文(right join)のusersテーブルに当たりますよね????

    キャンセル

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依存であり、結合の構文に対する結果は定められている、といったところでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る