内部結合では双方のフィールドの値が一致(等号、不等号などを含めて条件に一致)したレコードしか取り出せませんが、現実の処理では「一方に存在していても、もう一方からは参照されていないレコード」を取り出したい場合があります。そのような場合には外部結合を行います。
- 参照されていないレコードを取り出す - ここまでに紹介した内部結合のSQLでは、仕入先ID=305の「テイコー産業」から仕入れている商品(仕入先IDフィールドが“305”のレコード)が存在しないため、実行結果には「テイコー産業」の名称が表示されませんでした。
これは、先述したように内部結合では「関連付けた双方のテーブルから、結合条件に一致するレコードだけを抽出する」ためです。しかし、実際の業務では「テイコー産業から仕入れている商品がない」ことを示す必要が生じる場合もあります。
「仕入先_mr」に存在するレコードをすべて表示し 「商品_mr」からそのレコードを参照している レコードは存在しない
ことを示すには、「仕入先_mr」を基準にした関連付けを行います。そのためには、以下のようなSQLを記述します。
SELECT A.商品ID, A.品名, A.仕入単価, A.仕入先ID, B.仕入先名 FROM 商品_mr A RIGHT OUTER JOIN 仕入先_mr B
ON A.仕入先ID = B.仕入先ID
- 値のないフィールドは“NULL”になる - 上記SQLの実行結果を見れば、「仕入先名」フィールドにこれまで表示されていなかった「テイコー産業」が表示されています。但し「商品_mr」のどのレコードからも参照されていないため、「商品ID」や「品名」など「商品_mr」テーブル側のフィールドの値には“NULL”が表示されます。
“NULL”は「値がないことを示す値」です。数値の「0」や空白文字ではありません。それらも「0という値」や「空白という値」と見なされますが、NULLはそういう「何もないことを意味する値さえ存在していない」ことを示します。
ところで、「仕入先ID」フィールドも“NULL”となっているのは、この「仕入先ID」がテーブル「商品_mr」から取り出したものだからです。SELECT命令でフィールド名の指定を以下のようにすれば、テーブル「仕入先_mr」の「仕入先ID」フィールドの値“305”が表示されます。
SELECT A.商品ID, A.品名, A.仕入単価, B.仕入先ID, B.仕入先名
- 外部結合 - このように、関連付けたどちらか一方(または両方)のテーブルに記録されたレコードをすべて表示する形の結合を「外部結合」と呼びます。例の場合は、「仕入先_mr」テーブルを基準にして結合したことになります。
外部結合では、JOIN演算子にRIGHT OUTERまたはLEFT OUTER修飾子を付けます。RIGHTの場合はJOIN演算子の右側に記述したテーブルが、LEFTの場合は左側に記述したテーブルが基準となり、そのテーブルの全レコードが表示されます。
続くONの後ろの条件式では、テーブルの左右の位置は関係ありません。基準とするテーブルをJOIN演算子の左右どちらに置くかで、RIGHT OUTERかLEFT OUTERかが決まることに注意しましょう。
なお、OUTERは省略できるので、RIGHT JOIN、LEFT JOINとしても構いません。記事中では「INNERに対するOUTER」という意味が分かるよう、OUTERを付けて表記します。
- 右外部結合と左外部結合 - 上の例では、
FROM 商品_mr A RIGHT OUTER JOIN 仕入先_mr B
ON A.仕入先ID = B.仕入先ID
としました。RIGHTを使った外部結合なので「右外部結合」と言います。JOIN演算子の右側に記述した「仕入先_mr」が基準となります。
LEFT OUTERとした場合は「左外部結合」となり、JOIN演算子の左側に記述したテーブルが基準となります。従って、上のSQLは以下のようにしても同じ結果となります。
SELECT A.商品ID, A.品名, A.仕入単価, A.仕入先ID, B.仕入先名 FROM 仕入先_mr B LEFT OUTER JOIN 商品_mr A
ON A.仕入先ID = B.仕入先ID
|
|
|