表を指定するFROM句
SQL文では、表の指定をFROM句で行います。SQL文では表の指定が必要になるので、すでにここまでに何度も使ってきました。しかし、ここまで使ってこなかった指定として、複数の表の指定があります。複数の表を指定するには、FROM句に複数の表名を、「,」(カンマ)で区切って指定します。書式 SELECT ...FROM <表名1>,<表名2>...
ところで、もしも2つの表を指定したとして、この2つに同じ名前の列があったらどうなるのでしょうか?例えば、つぎのような「表A」と「表B」の2つがあるとします。
表A
ナンバー | 名前 |
---|---|
112 | ValueA1 |
123 | ValueA2 |
113 | ValueA3 |
126 | ValueA4 |
131 | ValueA5 |
表B
コード | 名前 |
---|---|
112 | ValueB1 |
131 | ValueB2 |
ここで注目するのは、両方の表に「名前」列があることです。これら2つの表を指定して、「名前」列を表示させるSQL文を記述する「名前」列をどちらの表から取得して表示するかわからないため、エラーとなります。
SQL文 SELECT 名前 FROM 表A, 表B;
実行結果 エラーが発生しました。
この問題を解決するには、SELECT句の列を指定するところで、どの表から読み出すのか、次のように指定する必要があります。
書式 SELECT <表名>.<列名>, ... FROM <表名>,<表名>...
表名と列名を「.」(ピリオド)で接続して列を指定します。このように記述すると、たくさんの表を指定したSQL文であっても、読み出す列を一意に特定することができます。SQL文 SELECT 表A.名前 FROM 表A,表B WHERE 表A.ナンバー = 表B.コード;
実行結果
名前 |
---|
ValueA1 |
ValueA5 |
ここでは、WHERE句で「表A」の「ナンバー」列と「表B」の「コード」列の両方にあるものを、「表A」の「名前」列から読み出しています。このSQL文を見て気づくように、WHERE句の中でも表と列の両方を指定した書き方ができます。「<表名>.<列名>」の記述はどこでも使うことができます。
なお、2つの表に同じ名前の列がなければ、表名を指定しなくても問題なく動作します。しかし、表の列名はいつ追加されるかわからないので、SQL文を記述することきは「<表名>.<列名>」で記述しておくと、無用なトラブルを避けることができます。
別名による表の指定
表の指定には、別名を使うこともできます。これはここで解説した列の別名と同じです。表の名前が長いときや、わかりづらいときに、FROM句で表に別名を指定すると、その別名を列の選択や、WHERE句での指定に使うことができます。
【SQLの基礎知識⑩】 データ問合せの基本
この章では、SQLの基本中の基本と言っていいSELECT文について解説しています。また、重複した値をまとめるDISTINCTについても説明しています。いちれべ.comは、オラクル、MS-SQL、MS-Access で使用可能か一目でわかるサイトです。
書式 ORACLE MS-SQL SELECT <別名>.<列名>, ・・・ FROM <表名1 別名1>,<表名1 別名2>, ・・・ MSAccess SELECT <別名>.<列名>, ・・・ FROM <表名1> AS <別名1>,<表名1> AS <別名2>, ・・・
列名の別名と同じように、ここでは記述しませんが、MSAccessでは「AS」が必要になります。それでは、先ほどのSQL文を、別名を使って記述してみます。
SQL文 SELECT A.名前 FROM 表A A, 表B B WHERE A.ナンバー=B.コード;
実行結果
名前 |
---|
ValueA1 |
ValueA5 |
適切に別名をつけると、SQL文を簡潔にでき、プログラミングの効率が上がるので、有効に活用しよう。
表の結合について
実際の業務では、複数の表を使ってさまざまな処理を行っています。また、データ処理では、複数の表でさまざまな演算を行い、新たな表を作り出し、さらにその表を組合せてデータ処理を行うこともあります。 こうした、複数の表をつなぎ合わせる処理を結合(JOIN)といいます。結合には次のような種類があります。- 交差結合
- 自然結合 ①内部結合 ②外部結合
交差結合
2つの表を直積により結合することを交差結合またはクロス結合といいます。この結合は最も単純な結合です。書式 MS-SQL SELECT <列名1> ・・・ FROM <表1> CROSS JOIN <表2> ORACLE MS-SQL MSAccess SELECT <列名1> ・・・ FROM <表1> , <表2>
では実際に交差結合の例を見ていきましょう。次の2つの表を交差結合してみます。表 : 名前リスト
社員番号 | 姓 | 名 | 勤務地コード |
1001 | 山田 | 花子 | 123 |
1022 | 斉藤 | 隆 | 223 |
1056 | 佐藤 | 一郎 | 223 |
表:事業所リスト
事業所コード | 事業所名 |
123 | 品川事業所 |
223 | 赤坂支社 |
301 | 横浜営業所 |
SQL文 MS-SQL SELECT * FROM 名前リスト CROSS JOIN 事業所リスト ORACLE MS-SQL MSAccess SELECT * FROM 名前リスト, 事業所リスト 実行結果
この結果からわかるように、「名前リスト」表と「事業所リスト」表の行同士の組合せがすべて結果として返されています。列はそれぞれの表の列数を足した数に、行はそれぞれの表の行数を掛けた数になります。社員番号 | 姓 | 名 | 勤務地コード | 事業所コード | 事業所名 |
1001 | 山田 | 花子 | 123 | 123 | 品川事業所 |
1022 | 斉藤 | 隆 | 223 | 123 | 品川事業所 |
1056 | 佐藤 | 一郎 | 223 | 123 | 品川事業所 |
1001 | 山田 | 花子 | 123 | 223 | 赤坂支社 |
1022 | 斉藤 | 隆 | 223 | 223 | 赤坂支社 |
1056 | 佐藤 | 一郎 | 223 | 223 | 赤坂支社 |
1001 | 山田 | 花子 | 123 | 301 | 横浜営業所 |
1022 | 斉藤 | 隆 | 223 | 301 | 横浜営業所 |
1056 | 佐藤 | 一郎 | 223 | 301 | 横浜営業所 |
自然結合 ①内部結合
自然結合とは、一方の表にある列の値と、もう一方の表のある列の値が同じ行を結び付ける結合です。このような結合を「等結合」と呼ぶこともあります。自然結合は「内部結合」と「外部結合」に分かれます。ここではまず内部結合から解説していきます。 内部結合(INNER JOIN)とは、一方の表の列の値ともう一方の表の列の値が同じ行だけを結合することを言います。内部結合は最もよく使う結合です。ORACLEでは、INNER JOINキーワード、ONキーワードに対応していないため、WHERE句の記述で内部結合を行います。他のRDBMS製品でも、INNER JOINキーワードやONキーワードを使わなくてもWHERE句の記述により内部結合を行うことができます。 書式 MS-SQL MSAccess SELECT ・・・ FROM <表1> INNER JOIN <表2> ON <表1>.<列1> = <表2>.<列2> ORACLE MS-SQL MSAccess SELECT ・・・ FROM <表1>, <表2> WHERE <表1>.<列1> = <表2>.<列2>
この記述は、2つの表の間で対応する列を指定する記述です。それぞれで指定された列の値が同じ行が結果として返されます。 交差結合では全ての組合せが返されましたが、内部結合では、その中から条件により抽出されたもにとなります。この結合の条件を「結合条件」と呼びます。 記述自体はWHERE句に使われる通常の条件式と同じなのですが、条件が真になったときに動作が異なります。WHERE句に書かれた通常の条件式の場合には、条件が真になったばあには結果としてその行が返されます。子に対して結合条件が真になると、行に結合が行われます。 実際の使用例を見てみましょう。表 : 顧客マスタ
顧客コード | 名前 | 電話番号 |
110 | 山田花子 | 0312341234 |
112 | 斉藤隆 | 0451231234 |
115 | 佐藤信也 | 0354325432 |
120 | 森葉子 | 0434444444 |
122 | 小泉加奈子 | 0311221122 |
表:売上リスト
商品コード | 商品名 | 販売価格 | 販売日 | 顧客コード |
1100 | レンズなしカメラ | 1100 | 20010601 | 112 |
1300 | 透明なインク | 180 | 20010601 | 112 |
1100 | レンズなしカメラ | 1200 | 20010602 | 115 |
1201 | 角のない豆腐 | 400 | 20010602 | 120 |
1301 | 開かない蓋 | 480 | 20010603 | 122 |
SQL文 MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ INNER JOIN 売上リスト ON 顧客マスタ.顧客コード=売上リスト.顧客コード;
SQL文 ORACLE MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格
FROM 顧客マスタ, 売上リスト WHERE 顧客マスタ.顧客コード=売上リスト.顧客コード;
実行結果
「顧客マスタ」表の「顧客コード」列と「売上リスト」表の「顧客コード」列の値が同じ5行だけが結果として返されました。 また、さらに複数の表を結合することもできます。INNER JOIN句を使う場合には、INNER JOINを繰り返し記述していきます。1つ目の結合の記述を「( )」で囲み、最初に結合が行われるようにし、その結果に対してさらに内部結合するように記述します。WHERE句を使う場合には、FROM句に表名を追加し、WHERE句内に結合条件をすべてAND演算子でつないで記述します。 ここでは、「顧客マスタ」表と「売上リスト」表に、さらに次の「商品マスタ」表を結合してみます。名前 | 商品名 | 販売価格 |
斉藤隆 | レンズなしカメラ | 1100 |
斉藤隆 | 透明なインク | 180 |
佐藤信也 | レンズなしカメラ | 1200 |
森葉子 | 角のない豆腐 | 400 |
小泉加奈子 | 開かない蓋 | 480 |
表:商品マスタ
商品コード | 商品名 | 販売価格 | 販売元 |
1100 | レンズなしカメラ | 1100 | びっくり愛 |
1300 | 透明なインク | 180 | うつけ屋 |
1201 | 角のない豆腐 | 400 | 裸の大様堂 |
1301 | 開かない蓋 | 480 | 非実用INC |
SQL文 MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 商品マスタ.商品単価, 売上リスト.販売価格 FROM (顧客マスタ INNER JOIN 売上リスト ON 顧客マスタ.顧客コード=売上リスト.顧客コード) INNER JOIN 商品マスタ ON 売上リスト.商品コード=商品マスタ.商品コード;
ORACLE MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 商品マスタ.商品単価, 売上リスト.販売価格 FROM 顧客マスタ, 売上リスト, 商品マスタ WHERE 顧客マスタ.顧客コード=売上リスト.顧客コード AND 売上リスト.商品コード=商品マスタ.商品コード;
実行結果
なお、INNER JOINキーワードやONキーワードが使えるRDBMS製品を使っている場合には、WHERE句に結合条件を記述するよりも、これらのキーワードを使ったほうが良いでしょう。それは、表と表の結合関係がひと目でわかるだけでなく、通常の条件式との区別も容易になるからです。 また、一部のRDBMS製品では、INNER JOINキーワードの「INNER」を省略することもできます。そのため次のような記述も可能です。名前 | 商品名 | 商品単価 | 販売価格 |
斉藤隆 | レンズなしカメラ | 1200 | 1100 |
斉藤隆 | 透明なインク | 180 | 180 |
佐藤信也 | レンズなしカメラ | 1200 | 1200 |
森葉子 | 角のない豆腐 | 400 | 400 |
小泉加奈子 | 開かない蓋 | 500 | 480 |
SELECT 顧客マスタ.名前, 売上リスト.商品名, 商品マスタ.商品単価
FROM 顧客マスタ JOIN 売上リスト ON 顧客マスタ.顧客コード=売上リスト.顧客コード;
省略はすべての製品で可能な訳ではないので、マニュアルなどで仕様を確認してください。内部結合と検索条件の指定
内部結合を行った結果に対して、さらに検索条件を設定することもできます。このとき結合は、WHERE句で検索条件の評価を行ううよりも先に実行されます。まずは結合し、その結合で作成された表に対して条件判断が行われることになります。 検索条件の指定はWHERE句に記述します。INNER JOINキーワードを使ていない場合はWHERE句にAND演算子を使って記述します。SQL文 MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ INNER JOIN 売上リスト ON 顧客マスタ.顧客コード=売上リスト.顧客コード WHERE 売上リスト.販売日='20010602';
ORACLE MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ, 売上リスト WHERE 顧客マスタ.顧客コード=売上リスト.顧客コード AND 売上リスト.販売日='20010602';
実行結果
先ほどの内部結合に抽出された5件から、さらに販売日により条件を絞り込んでいるので、2件だけが結果として返されました。名前 | 商品名 | 販売価格 |
佐藤信也 | レンズなしカメラ | 1200 |
森葉子 | 角のない豆腐 | 400 |
自然結合 ②外部結合
内部結合では、複数の表の間で対応する列の値が等しいものだけが結合され、結果として返されました。そのため、どちらかにしか存在しない値をもつ行は結合されませんでした。しかし、処理の目的によってはある表だけは必ず残したいという場合があります。こういった場合に用いるのが外部結合(OUTER JOIN)です。外部結合には、結合の方向により2つの種類があります。- 左外部結合
- 右外部結合
左外部結合
左外部結合は、先に記述した左側の表を優先し、左側の表に関してはすべての行を残す結合です。 書式 MS-SQL MSAccess SELECT ・・・ FROM <表1> LEFT OUTER JOIN <表2> ON <表1>.<列1> = <表2>.<列2> ORACLE SELECT ・・・ FROM <表1>, <表2> WHERE <表1>.<列1> = <表2>.<列2>(+) MS-SQL SELECT ・・・ FROM <表1>, <表2> WHERE <表1>.<列1> *= <表2>.<列2>
SQL文 MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格
FROM 顧客マスタ LEFT OUTER JOIN 売上リスト
ON 顧客マスタ.顧客コード=売上リスト.顧客コード;
ORACLE SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ, 売上リスト WHERE 顧客マスタ.顧客コード=売上リスト.顧客コード(+);
MS-SQL SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ, 売上リスト WHERE 顧客マスタ.顧客コード *= 売上リスト.顧客コード;
実行結果
名前 | 商品名 | 販売価格 |
山田花子 | ||
斉藤隆 | レンズなしカメラ | 1100 |
斉藤隆 | 透明なインク | 180 |
佐藤信也 | レンズなしカメラ | 1200 |
森葉子 | 角のない豆腐 | 400 |
小泉加奈子 | 開かない蓋 | 480 |
表:売上リスト
商品コード | 商品名 | 販売価格 | 販売日 | 顧客コード |
1100 | レンズなしカメラ | 1100 | 20010601 | 112 |
1300 | 透明なインク | 180 | 20010601 | 112 |
1100 | レンズなしカメラ | 1200 | 20010602 | 115 |
1201 | 角のない豆腐 | 400 | 20010602 | 120 |
1301 | 開かない蓋 | 480 | 20010603 | 122 |
表 : 顧客マスタ
顧客コード | 名前 | 電話番号 |
110 | 山田花子 | 0312341234 |
112 | 斉藤隆 | 0451231234 |
115 | 佐藤信也 | 0354325432 |
120 | 森葉子 | 0434444444 |
122 | 小泉加奈子 | 0311221122 |
右外部結合
右外部結合は、左外部結合とは反対に、後で指定した右側の表を優先し、右側の表に関してはすべての行を残す結合です。 書式 MS-SQL MSAccess SELECT ・・・ FROM <表1> RIGHT OUTER JOIN <表2> ON <表1>.<列1> = <表2>.<列2> ORACLE SELECT ・・・ FROM <表1>, <表2> WHERE <表1>.<列1>(+) = <表2>.<列2> MS-SQL SELECT ・・・ FROM <表1>, <表2> WHERE <表1>.<列1> =* <表2>.<列2>
SQL文 MS-SQL MSAccess SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格
FROM 顧客マスタ RIGHT OUTER JOIN 売上リスト
ON 顧客マスタ.顧客コード=売上リスト.顧客コード;
ORACLE SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ, 売上リスト WHERE 顧客マスタ.顧客コード(+) = 売上リスト.顧客コード;
MS-SQL SELECT 顧客マスタ.名前, 売上リスト.商品名, 売上リスト.販売価格 FROM 顧客マスタ, 売上リスト WHERE 顧客マスタ.顧客コード =* 売上リスト.顧客コード;
実行結果
この表では、名前が左側の表からの列になります。ここではNULLになっている行はありません。なぜなら「売上リスト」表が右側になっているため、この表の中に顧客名が入っていないことはないためです。名前 | 商品名 | 販売価格 |
斉藤隆 | レンズなしカメラ | 1100 |
斉藤隆 | 透明なインク | 180 |
佐藤信也 | レンズなしカメラ | 1200 |
森葉子 | 角のない豆腐 | 400 |
小泉加奈子 | 開かない蓋 | 480 |
関連リンク
次の章へ進む

【SQLの基礎知識⑮】 副問い合わせ(サブクエリ)
SQL文の中にさらにSQL文を追加して記述することを副問合せやサブクエリと呼びます。ここではSQLにおける副問合せついて解説します。いちれべ.comは、オラクル、MS-SQL、MS-Access で使用可能か一目でわかるサイトです。
目次

【SQLの基礎知識】基本ルールや基礎の基礎をマスターしよう
こちらの記事を読み進めることで、SQLの基礎が充分に身に付きます。これからSQLを身に着けたい初心者・入門者の方に最適です。データベース製品ごとに表現方法が異なることがありますので、ある程度SQLのスキルがある方も利用できるサイトです。