テーブルの結合 JOIN
テーブルの結合とは、複数のテーブルデータを組み合わせる方法です。
例えば、商品マスターには商品名があって売上データには商品IDのみがある場合に、売上データから商品名を知ることができません。
そのような場合には商品マスターと売上データを結合することで商品名のある売上データを取得することができます。
テーブルの結合は、JOIN 句を使用して複数のテーブルを組み合わせます。
JOIN 句のみを複数のテーブルを結合すると、それぞれのテーブルのデータの全組み合わせで返されます。
JOIN 句のみではすべての組み合わせを返します。組み合わせに条件を設定して任意の行のみを抽出するには ON を付加します。
テーブルの結合には外部結合と内部結合があります。JOIN 句はデフォルトの設定では内部結合です。
JOIN 句の代わりに INNER JOIN 句によって明確に内部結合であることを指定することもできます。
例のデータについて
以降の例では、テーブル
ページの外部キー制約( FOREIGN KEY )
の作成例で使用したデータを使用しています。
以下のようなデータです。
JOIN
JOIN 句は複数のテーブルを結合します。JOIN のみでテーブルを指定するとすべての組み合わせになります。
以下のデータは上記の例のデータについて
を使用しています。
すべての組み合わせではなく、組み合わせ条件を設定するには ON 句を使用します。ON 句を使用することで条件にあった組み合わせのみを抽出します。
ON 結合条件
JOIN に対して ON 句によってテーブルの結合条件を付加することができます。
全組み合わせに対して ON 句による条件をもつ行のみが抽出されます。
このようなテーブルの結合には外部結合と内部結合があります。
JOIN 句はデフォルトでは内部結合になります。内部結合を明確に指定するには INNER JOIN を使用します。
非等結合
ON 句における条件でイコール=
で評価される場合は等結合といいます。
範囲による条件も指定することができます。範囲による結合は非等結合といいます。
以下の例は非等結合ができることを示しているだけで意味がありません。
ON 句と WHERE 句
テーブル結合に WHERE 句による抽出を加えるとその条件による行データのみが取得できます。
このことは ON 句で AND を使用しても同じことが起きます。
ただし、処理の順番に違いがあります。同じ結果が得られるのですがコードの意味が目的とした手段に準じているかが大事です。
INNER JOIN
内部結合を明確に指定するには INNER JOIN を使用します。INNER JOIN も ON 句によって全組み合わせから条件に合う行のみが抽出されます。
INNER JOIN は JOIN のデフォルトの状態ですが、多くの場合は内部結合を指定には INNER JOIN を使用します。
サブクエリとの結合
結合するテーブルはサブクエリにすることもできます。
上記の例では SELECT 文のサブクエリで抽出された行データを元に結合されます。そのために amount => 50 である行との結合になっています。
自己結合
同じテーブルを複数回に結合することができます。
例えば、ユーザーテーブル user_ を作成したとします。事業におけるユーザーには上司であったり部下であったりという相関関係があることがあります。
user_ テーブルですべてのユーザーを記録するのですが、ユーザーごとの上司を同じ user_ テーブルの id で記録し自己結合
するようにします。
PostgreSQL ではUNSIGNED
が使えませんのでmanager_id BIGINT
とします。
確認用のデータを入力します。
上記の user_test テーブルを自己結合
で参照しています。ここでは外部結合LEFT OUTER JOIN
を使用しています。
外部結合は結合する行データがない場合でも抽出の対象になるものです。LEFT OUTER JOIN
とRIGHT OUTER JOIN
があります。
用途によって使い分けます。
3つ以上のテーブルの結合
3つの以上のテーブルを結合する方法はいくつかあるのですが、ここでは1つのテーブルが2つのテーブルの外部キー制約( FOREIGN KEY )を持つ場合を例に上げます。
例えば、sales_slip テーブルに販売担当者を加えたいとします。
新たに user_ テーブルを作成し、sales_slip テーブルに外部キー制約を設けます。
データは以下のようなものにします。
sales_slip テーブルから user_ テーブルを外部キー制約を設けます。
上記の例は MySQL における例です。PostgreSQL ではuser_id INT
とします。
既存のテーブを変更する場合は ALTER クエリーを使用します。
PostgreSQL では user_id
は BIGINT または INT です。
sales_slip テーブルの user_id を以下のように更新します。
sales_slip テーブルと goods、user_テーブルを JOIN で結合してみます。
5 ✕ 5 ✕ 3 の組み合わせで 125 通りが表示されますがここでは割愛します。
sales_slip の全行データとその商品名と担当したユーザー名が表示される組み合わせの条件は、salse_slip.goods_id = goods.id、salse_slip.user_id = user_.id ですので、このことを ON 条件にそれぞれ加えます。
売り上げた商品の名称と担当したユーザー名が取得できています。
外部結合
テーブルの結合には内部結合と外部結合があります。外部結合では結合するテーブルの一方のデータをすべて網羅します。
JOIN
のみで内部結合として処理されますが、外部結合の場合はOUTER JOIN
と明記する必要があります。
さらにOUTER JOIN
の前にLEFT
またはRIGHT
といった先のテーブルの内容を優先するのか後のテーブルのデータを優先するのかと、ON
によって結合条件を設定しないとエラーになります。
外部結合について詳しくは外部結合 OUTER JOIN
ページを参照してください。
自然結合
SQL の自然結合とは、NATURAL JOIN を使用した結合条件をデータベース任せにするものです。NATURAL JOIN では ON 句を必要としてません。
自然結合は、必ずしも想定通りになるとは限りません。また、データベースによっても結果が変わる可能性があります。
ON 句によって結合条件を設定したほうがよいようです。