Shoeisha Technology Media

資格Zine(しかくジン)

記事種別から探す

結合の使用による複数の表のデータの出力

  • LINEで送る
  • このエントリーをはてなブックマークに追加
林 優子[著]
2016/09/13 14:00

 SQLの学習を始めたばかりの方にとって、急に難しく感じるのが「結合」のようです。取り出したいデータが入っている列が2つ以上の表(テーブル)に定義されているので、1つ目の表名をFROM句に、2つ目以降の表名を1つずつJOIN句に記述していけばいいだけなんですけどね。ただし、細かい注意事項がちょこちょこあって、試験ではそこが問われたりします。

NATURAL JOINとUSING

異なるレコード(行)を1つのレコードとして出力する方法を結合(JOIN)といいます。また、異なるレコードどうしが結合できる/できないの条件を結合条件、互いのレコードの値が一致することを条件とする場合を等価結合といいます。

結合の基本構文は次のとおりです。

構文 結合の基本構文
SELECT (表名n.)列名, ……
FROM   表名1
JOIN   表名2
ON     表名1.結合列名 = 表名2.結合列名

結合条件はONで記述します。ただし、等価結合では結合条件に指定する列名は、結合する表どうしで同じである場合が多いので、いちいちON句に結合条件を記述しなくても、列名で察してくれないかなと思うことがあります。それを実現してくれるのが、自然結合(NATURAL JOIN)です。

また、結合列以外にも同じ名前の列が存在するという場合にはJOIN USINGを使用し、「結合条件に使用する列は(同じ名前の列が複数ある中で)この列だよ」と指定できるのでした。

それを踏まえて、次の問題を考えてみましょう。

問1

次の3つの表を確認してください。

 SQL> desc customers
 名前                          NULL?    型
 ----------------------------- -------- --------------------
 CUST_ID                       NOT NULL NUMBER
 CUST_FIRST_NAME               NOT NULL VARCHAR2(20)
 CUST_LAST_NAME                NOT NULL VARCHAR2(40)
 CUST_GENDER                   NOT NULL CHAR(1)
 CUST_YEAR_OF_BIRTH            NOT NULL NUMBER(4)
 CUST_MAIN_PHONE_NUMBER        NOT NULL VARCHAR2(25)
 CUST_EMAIL                             VARCHAR2(50)
 
 
 SQL> desc products
 名前                          NULL?    型
 ----------------------------- -------- --------------------
 PROD_ID                       NOT NULL NUMBER(6)
 PROD_NAME                     NOT NULL VARCHAR2(50)
 PROD_DESC                     NOT NULL VARCHAR2(4000)
 PROD_LIST_PRICE               NOT NULL NUMBER(8,2)
 PROD_MIN_PRICE                NOT NULL NUMBER(8,2)
 
 SQL> desc sales
 名前                          NULL?    型
 ----------------------------- -------- --------------------
 PROD_ID                       NOT NULL NUMBER
 CUST_ID                       NOT NULL NUMBER
 TIME_ID                       NOT NULL DATE
 CHANNEL_ID                    NOT NULL NUMBER
 PROMO_ID                      NOT NULL NUMBER
 QUANTITY_SOLD                 NOT NULL NUMBER(10,2)
 AMOUNT_SOLD                   NOT NULL NUMBER(10,2)  

次の問い合わせを実行しました。

SELECT DISTINCT p.prod_id,prod_name,cust_id,cust_last_name
FROM   products p
NATURAL JOIN  sales s
JOIN customers c
USING (cust_id);  

この問い合わせに対して、正しい記述を選びなさい。

  • a. 正常に実行される
  • b. 1つのSQLに、NATURAL JOINとJOIN USINGの両方を使うことはできないので、エラーが発生する
  • c. NATURAL JOINで使用する結合列に表名を指定することはできなので、エラーが発生する
  • d. JOIN USINGで使用する結合列は表名を指定しなければいけないので、エラーが発生する
  • e. NATURAL JOINは3つ以上の表の結合には使用できないので、エラーが発生する
  • f. JOIN USINGは3つ以上の表の結合には使用できないので、エラーが発生する

まずは、設問のSQLを実行してみましょう。

SQL> SELECT DISTINCT p.prod_id,prod_name,cust_id,cust_last_name
  2  FROM   products p
  3  NATURAL JOIN  sales s
  4  JOIN customers c
  5  USING (cust_id);
SELECT DISTINCT p.prod_id,prod_name,cust_id,cust_last_name
                *
行1でエラーが発生しました。:
ORA-25155: NATURAL結合で使用される列は修飾子を持てません。

実行結果から分かるように、選択肢aは不正解で、正解は選択肢cです。 NATURAL JOINおよびJOIN USINGは、ON句を使用して結合条件を記述しない代わりに、同じ名前の列を結合列として使用します。 このとき、結合列を表名で修飾してはいけません

設問のSQLから、products表とsales表の結合列であるprod_idの表名修飾をなくしただけのSQLを実行してみましょう。

SQL> SELECT DISTINCT prod_id,prod_name,cust_id,cust_last_name
  2  FROM   products p
  3  NATURAL JOIN  sales s
  4  JOIN customers c
  5  USING (cust_id);

   PROD_ID PROD_NAME                         CUST_ID    CUST_LAST_NAME
---------- --------------------------------- ---------- ------------
        13 5MP Telephoto Digital Camera      2310       Hale
        13 5MP Telephoto Digital Camera      5681       Wagner
(途中省略)
       147 Extension Cable                   7390       Ziluca
       147 Extension Cable                   2115       Overton

279954行が選択されました。

正常に実行されることから、次のことが分かります。

  • 1つのSQLに、NATURAL JOINJOIN USINGの両方を使うことができる(選択肢bは不正解)
  • JOIN USINGで使用する結合列は、表名を指定する必要がない(選択肢dは不正解)
  • NATURAL JOINは、3つ以上の表の結合には使用できる(選択肢eは不正解)
  • JOIN USINGは、3つ以上の表の結合には使用できる(選択肢fは不正解)
  • NATURAL JOINJOIN USING句を使用した結合のSELECT句に、DISTINCTを使用することができる

3つ以上の表の結合を行う場合、NATURAL JOINJOIN USINGだけでなく、後述するON句を使用した外部結合でも自己結合でも、何でも混在できることも合わせて覚えておいてください。

また、どんなときでも、NATURAL JOINJOIN USINGの結合列は表名で修飾してはいけませんが、結合列以外は表名で修飾できること、それどころか、ON句を使用した結合の場合は結合列(列名が同じ)の表名修飾が必要であることも忘れないでください。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 林 優子(ハヤシ ユウコ)

    日本オラクル株式会社の教育ビジネスのスタートアップを全面的に支援し、バージョン5の頃からOracleに携わるベテラン講師として知る人も多い。Oracle認定講師を表彰するExcellent Instructorを連続受賞。1ランク上のITスペシャリスト育成を目標に、データベース分野にとどまらず「プレゼンテーション」、「ロジカルシンキング」などのトレーニングも手がけている。著書に『オラクルマスター教科書』シリーズ(翔泳社)、『プロとしてのデータモデリング入門』(SBクリエイティブ)など。その他、雑誌執筆、著書・メディア出演も多数。

バックナンバー

連載:めざせオラクルマスターホルダー! Oracle DB 12c SQL基礎 弱点克服スクール

もっと読む

All contents copyright © 2015-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.0