Inner JoinとLeft/Right Outer Join をさらっと説明。 SQL超初心者の勉強。

2021-08-04

複数テーブルを結合する時に使う、Inner JoinとLeft Join (Left Outer Join)とRight Join(Right outer Join)の違いをさらっと説明します。

動作環境

SQL FIDDLEでMySQL5.6、PostgreSQL9.6で動作確認しました。
下記文章は主にPostgreSQLで仕様で調べています。

Inner JoinとOuter Joinの違い

Inner Joinは内部結合と呼ばれており、Outer Joinは外部結合と呼ばれています。
Inner Joinは結合時に指定した値が2つのテーブルに存在している場合、項目として表示されます、
それに対してOuter Joinはどちらかのテーブルを基準としてない値はnullとして表示します。

Outer JoinにはLeft outer joinと Right Outer Joinがあります。
Left Outer Joinの方が使用頻度が高いです。(Right Joinはあまりみかけない。)

構文

○構文
SELECT columnA, columnB ... FROM tableA INNER JOIN tableB ON rule

○実際に書いた場合
SELECT
    itemid,
    itemname
FROM
    item
INNER JOIN
    stockControl
on
    item.ItemID = stockControl.ItemID
order by
    item.itemId

使用するテーブル

以下のテーブルを使用します。テーブルは2つあります。

Itemiditemnamequantityarea
2プリン25大阪
3ゼリー30東京
4ティラミス15大阪
5ヨーグルト30東京
6ゼリー20大阪
item テーブル
itemiditemnamestockarrivedate
1ゼリー402020-04-20
2プリン652020-04-20
4ティラミス402020-04-22
5ヨーグルト102020-04-20
stockControlテーブル

itemテーブルにはItemID 1 stockControlテーブルにはItemID 3 と 6から始まる行が存在していないことがInner JoinとLeft Joinの違いを知る上では重要です。

準備

上記テーブルを作成するコードです。実際に動きを見たい方は活用ください。

-- CREATE文 item テーブル
CREATE TABLE item (
ItemID numeric(8, 0) unique not null,
ItemName character varying (20),
Quantity numeric(8, 0),
AREA character varying (20),
primary key(ItemID)
);
-- itemテーブル用INSERT文
insert into item
values(0002, 'プリン', 25, '大阪'),
(0003, 'ゼリー', 30, '東京'),
(0004, 'ティラミス', 15,'大阪'),
(0005, 'ヨーグルト', 30, '東京'),
(0006, 'ゼリー', 20, '大阪');

-- CREATE文 stockControl テーブル
CREATE TABLE stockControl (
ItemID numeric(8, 0) unique not null,
ItemName character varying (20),
Stock numeric(8, 0),
ArriveDate DATE,
primary key(ItemID)
);

-- stockControlテーブル用INSERT文
insert into stockControl
values(0001, 'ゼリー', 40, '2020-04-20'),
(0002, 'プリン', 65, '2020-04-20'),
(0004, 'ティラミス', 40, '2020-04-22'),
(0005, 'ヨーグルト', 10, '2020-04-20');

それでは実際に書いていきます。Itemテーブルを軸に書いていきます。

Inner Joinでテーブルを結合

ItemIdを結合の条件に2つのテーブルをInner Joinで結合します。

SELECT
    *
FROM
    item
inner join
    stockControl
on
    item.ItemID = stockControl.ItemID
order by
    item.itemId

■ 結果

itemiditemnamequantityareaitemiditemnamestockarrivedate
2プリン25大阪2プリン652020-04-20
4ティラミス15大阪4ティラミス402020-04-22
5ヨーグルト30東京5ヨーグルト102020-04-20

itemテーブルにはItemID 1 が stockControlテーブルにはItemID 3 と 6から始まる行が存在しないため結合時に削除されていることがわかります。

Left (outer) Joinでテーブルを結合

ItemIdを結合の条件に2つのテーブルをLeft Joinで結合します。(outerは省略可)

SELECT
    *
FROM
    item
left join
    stockControl
on
    item.ItemID = stockControl.ItemID
order by
    item.itemId

■ 結果

itemiditemnamequantityareaitemiditemnamestockarrivedate
2プリン25大阪2プリン652020-04-20
3ゼリー30東京(null)(null)(null)(null)
4ティラミス15大阪4ティラミス402020-04-22
5ヨーグルト30東京5ヨーグルト102020-04-20
6ゼリー20大阪(null)(null)(null)(null)

itemテーブルにはItemID 1 がないためstockControlテーブルのItemID 1は結合できず削除。stockControlテーブルにはItemID 3 と 6から始まる行が存在しないため結合時にnullで表示されていることがわかります。

左側に結合時にnullを作成しない状態。

Right (outer) Joinでテーブルを結合

ItemIdを結合の条件に2つのテーブルをRight Joinで結合します。(outerは省略可)

SELECT
    *
FROM
    item
Right join
    stockControl
on
    item.ItemID = stockControl.ItemID
order by
    stockControl.itemId

■ 結果

itemiditemnamequantityareaitemiditemnamestockarrivedate
(null)(null)(null)(null)1ゼリー402020-04-20
2プリン25大阪2プリン652020-04-20
4ティラミス15大阪4ティラミス402020-04-22
5ヨーグルト30東京5ヨーグルト102020-04-20

itemテーブルにはItemID 1 がないがstockControlテーブルには値があるため結合時にnullで表示。stockControlテーブルにはItemID 3 と 6から始まる行が存在しないため結合時に削除されていることがわかります。

右側に結合時にnullを作成しない状態。

Outer Joinはどちら側を優先的に表示したいかでleftとRightの使い分け方が決まります。

おわり

Inner Join を内部結合、Outer join を外部結合ともいいますが、日本語になっただけなのに難しく感じるのなんででしょうね。