テーブル結合について (Part.3) - 内部結合を極めよう

第7回となる今回は、実践的な問題を解きながら、利用頻度の高い内部結合について深掘りしていきます。

久保 司

2023年4月25日 6:30

はじめに

今回は、「テーブル結合」のPart.3として、まず前回(Part.2)で出題した問題の答え合わせを行い、続けて実践的な問題を解きながら「内部結合」について深掘りしていきます。内部結合は、よく使われるテーブル結合なので、しっかり理解していきましょう。

訓練に使用するデータベースは、これまでに引き続き、いつもの「SQLite」を使用していきます。

それでは、今回もハッスルして訓練に行ってみましょう!

「自然結合」の問題(前回)の答え合わせ

【問題】
自然結合で同じ名前の項目がないテーブルを結合した場合、結果はどうなるでしょうか。

【解答】
自然結合の基本的な構文は下記のようになります。

SELECT 項目X, … FROM テーブルY
NATURAL INNER JOIN テーブルZ;

それでは、前回で登場したテーブルで同じ名前の項目がない、サイズテーブル(tbl_size)と部署テーブル(tbl_dept)を使用して確認してみましょう。データも前回で作成したデータを利用します。今回が初めての方は前回の内容を参照して、それぞれのテーブルを作成しデータを挿入してください。

始めにサイズテーブルに登録されている内容を確認してみましょう。

.headers on
.mode column

SELECT *  FROM tbl_size;

*「.headers」「.mode」は表示内容の設定コマンドなので、ログイン後に1回実行すればOKです。

次に、部署テーブルの内容を確認してみましょう。

SELECT *  FROM tbl_dept;

それぞれのデータを確認できたので、実際に2つのテーブルを自然結合で結合してみます。

SELECT S.* ,  D.* FROM tbl_size AS S
NATURAL INNER JOIN tbl_dept AS D;

結果は、上図のように全てのデータの組み合わせが表示されます。気付いた方もいらっしゃると思いますが、交差結合(CROSS JOIN)した場合と同じ結果となります。

このように、異なるテーブル結合を使用しても同じ結果になる場合もあるので、色々と試してみてください。また、それぞれのテーブルの全ての項目を表示するために、「S.*」「D.*」のように項目名を省略してアスタリスクを使用しています。

「内部結合」の深掘り

ここからは、実際に「内部結合」を利用した問題を解きながら、内部結合を深掘りしていきます。

(1)受注商品の一覧

1問目は、ER図にある商品マスタ、倉庫マスタ、受注データ、受注明細データの4つのテーブルを利用した内部結合です。

【問題】
2021年10月に取引があった受注の商品一覧を表示しなさい。

表示項目は以下とする(エイリアスを使用し→の項目名とする)。

  • WH_CODE → W_CD
  • WH_NAME → W_NM
  • ITEM_CODE → I_CD
  • ITEM_NAME → I_NM
  • ORDER_NO → OD_NO
  • QUANTITY → OD_QT
表示順
  1. 倉庫コードの昇順
  2. 商品コードの昇順
  3. 受注数量の降順

【使用するテーブルのER図(半角:物理名/全角:論理名)】
※ER図(Entity Relationship Diagram)とは、テーブル(Entity)とテーブル同士の関連(Relationship)を図に表したもので、データベース設計における代表的な設計図のことです(ここでは、詳細の説明は省略します)。

【準備】
使用するテーブルを作成し、データを挿入します。テーブルが多くて大変ですが、頑張りましょう!

【商品マスタCREATEコマンド】
CREATE TABLE ITEM_MST (
ITEM_CODE TEXT NOT NULL,
ITEM_NAME TEXT,
PRIMARY KEY(ITEM_CODE));
【商品マスタINSERTコマンド】
INSERT INTO ITEM_MST (ITEM_CODE,ITEM_NAME) VALUES
 ('100','BANANA'), ('110','APPLE'), ('120','ORANGE')
, ('130','GRAPE'), ('140','PEAR'), ('150','PERSIMMON')
, ('160','STRAWBERRY'), ('170','MELON'), ('180','WATERMELON');
【倉庫マスタCREATEコマンド】
CREATE TABLE WH_MST (
WH_CODE TEXT NOT NULL,
WH_NAME TEXT,
PRIMARY KEY  (WH_CODE))
【倉庫マスタINSERTコマンド】
INSERT INTO WH_MST (WH_CODE,WH_NAME) VALUES 
('100','WH_NO1'), ('200','WH_NO2'),('300','WH_NO3');
【受注テーブルCREATEコマンド】
CREATE TABLE ORDER_TBL (
ORDER_NO TEXT NOT NULL,
ORDER_DATE TEXT NOT NULL,
WH_CODE TEXT NOT NULL,
ORDER_AMNT INTEGER NOT NULL DEFAULT '0',
PRIMARY KEY(ORDER_NO));
【受注テーブルINSERTコマンド】
INSERT INTO ORDER_TBL
(ORDER_NO,ORDER_DATE,WH_CODE,ORDER_AMNT) VALUES
 ('OR010','2021-09-30','100','495')
, ('OR100','2021-10-01','100','1640')
, ('OR101','2021-10-05','200','2680')
, ('OR102','2021-10-10','200','720')
, ('OR103','2021-10-20','300','1780')
, ('OR104','2021-10-31','200','3160')
, ('OR200','2021-11-01','100','3560');
【受注明細テーブルCREATEコマンド】
CREATE TABLE ORDER_DETAILS (
ORDER_NO TEXT,
OD_ROW_NO INTEGER,
ITEM_CODE TEXT NOT NULL,
UNITPRICE INTEGER NOT NULL DEFAULT '0',
QUANTITY INTEGER NOT NULL DEFAULT '1',
PRIMARY KEY(ORDER_NO,OD_ROW_NO));
【受注明細テーブルINSERTコマンド】
INSERT INTO ORDER_DETAILS
 (ORDER_NO,OD_ROW_NO,ITEM_CODE,UNITPRICE,QUANTITY) VALUES
 ('OR010','1','150','99','5'), ('OR100','1','100','100','2')
, ('OR100','2','110','120','4'), ('OR100','3','120','140','3')
, ('OR100','4','130','540','1'), ('OR101','1','110','120','3')
, ('OR101','2','120','140','5'), ('OR101','3','130','540','3')
, ('OR102','1','110','120','6'), ('OR103','1','120','140','5')
, ('OR103','2','130','540','2'), ('OR104','1','100','100','1')
, ('OR104','2','110','120','5'), ('OR104','3','120','140','6')
, ('OR104','4','130','540','3'), ('OR200','1','160','890','4');

【解答例】

SELECT
      T1.WH_CODE             AS W_CD
    , T3.WH_NAME             AS W_NM
    , T2.ITEM_CODE           AS I_CD
    , T4.ITEM_NAME           AS I_NM
    , T1.ORDER_NO            AS OD_NO
    , T2.QUANTITY            AS OD_QT
FROM
    ORDER_TBL AS T1 -- ①
    INNER JOIN ORDER_DETAILS AS T2 -- ②
        ON T1.ORDER_NO = T2.ORDER_NO 
    INNER JOIN WH_MST AS T3 -- ③
        ON T1.WH_CODE = T3.WH_CODE 
    INNER JOIN ITEM_MST AS T4 -- ④
        ON T2.ITEM_CODE = T4.ITEM_CODE 
WHERE
    T1.ORDER_DATE BETWEEN '2021-10-01' AND '2021-10-31' -- ⑤
ORDER BY
    T1.WH_CODE ASC
    , T2.ITEM_CODE ASC
    , T2.QUANTITY DESC; -- ⑥

【説明】
 ① 受注日を絞り込むために、受注テーブルをメインテーブルとしています
 ② 受注数量を取得するために、受注明細テーブルを受注番号で内部結合しています
 ③ 倉庫名を取得するために、倉庫マスタを倉庫コードで内部結合しています
 ④ 商品名を取得するために、商品マスタを受注明細データの商品コードで内部結合しています
 ⑤ BETWEEN句で2021年10月の受注データを絞り込んでいます
 ⑥ 受注数量は降順で表示するため、DESCを指定しています

【結果】
受注日が2021年10月に含まれるデータが表示されていることが確認できます。4テーブルを使用しているので、各テーブルはAS句で別名を付けて簡素化しています。

テーブルが多いとSQL文も読み難くなるので、各項目の先頭にテーブルの別名を付けて、どのテーブルの項目か分かり易いように記述しています。

この記事のキーワード :

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30