Agent Grow Tech Notes
🕋

【応用情報】令和7年度春期(午後:問6 データベース)第2回 - SQL(その1)

に公開

今回も、令和7年度春期応用情報技術者試験午後問6「データベース」 について解説します。
前回の続きとなっておりますので、まだご覧になられていない場合はまずこちらからどうぞ。
【応用情報】令和7年度春期(午後:問6 データベース)第1回 - ER図

この記事は、下記の方々を対象としております。

  • 応用情報技術者試験を受験する、且つ午後にデータベースを選択する。
  • データベーススペシャリスト試験を受験するが、応用情報レベルから復習したい
  • 開発エンジニアでデータモデリングやDB関連の設計を担当する、もしくは目指している。

試験問題の構成や難易度、SQLや設計のポイントを整理しました。
下記の内容を全4回に分けてご紹介しています。

  • 第1回:設問1(ER図 - 複合主キー)
  • 第2回:設問2(今回)(SQL - 結合と集計)
  • 第3回:設問3(SQL - ソートと条件考察)
  • 第4回:設問4(テーブル定義の変更)

設問2:結合と集計

※出典:令和7年度 春期 応用情報技術者試験 午後 問題冊子

構文の構成を完成させる(空欄:c,d)

前半のSQLは、サブクエリが2つ(CKとUK)存在し、それらから項目を取得していることが分かります。
構文をいくつかのブロックに分け、SQLのルールに則り下記のように考えられます。

空欄cに『FROM』が入るのは、SELECT文でテーブルから項目を取得する基本中の基本です。

空欄dは、画像でも記した通り候補がいくつかあります。
内部結合か?外部結合か?を判断する必要がありますが、今回はSQL文だけで判断できます

まず、外部結合であることが分かります。
なぜなら、SELECT文でCOALESCE関数を使用しており、今回は内部結合にするとCOALESCE関数は必ず第1引数(下記画像ではA)しか取得しないので、COALESCE関数を使用する意味がないからです。

また、COALESCEの仕様により、CKが主体であるのが分かります。

SQL文の順番では、CKがUKより先に記載されています。
先に記載された方を主体にするのは、左外部結合(LEFT)なので、空欄dは『LEFT OUTER JOIN』 です。

原価の合計算出(空欄:e)

原価計を出すための構文を考えますが、すぐそばに売上計があるので、同じ理屈で考えられます。

売上計商品個数×単価したものを合計します。
ということは、原価計商品個数×原価したものを合計すれば良いのでは?
と、流用する思考ができれば簡単に解けます。

では、原価はどこから取得するのか?
上記画像の青で囲ったテーブルのいずれかに存在しますが、そもそもER図に原価は1つしかありませんので、すぐ見つかります。

商品テーブルの商品原価であることが分かったので、あとは売上計のマネをするだけです。
空欄eは『SUM(M.商品個数 * S.商品原価)』 です。

SQLを動かしてみよう

解説はしたものの、簡単に試せるのなら試した方が良いです!
PostgreSQLで書きますので、よろしければ試してみてください。
※簡単に試す方法はこちらの記事を参考にして下さい。

データサンプル

問題文には具体的なデータが無いので、私が考えたオリジナルをご紹介します。
まず、テーブル定義とデータです。

-- キャンペーン実施テーブル
CREATE TABLE キャンペーン実施 (
    キャンペーン番号      CHAR(4)
  , キャンペーン実施番号  INTEGER
  , キャンペーン種別      CHAR(1)
  , キャンペーン実施金額  NUMERIC
  , 開始年月日            DATE
  , 終了年月日            DATE
  , PRIMARY KEY (キャンペーン番号 ,キャンペーン実施番号)
);

INSERT INTO キャンペーン実施 VALUES
 ('CP01',1,'L',30000,'2025/1/1','2025/12/31')
,('CP01',2,'H',70000,'2025/1/1','2025/12/31')
,('CP02',1,'H',50000,'2025/1/1','2025/12/31')
,('CP02',2,'L',40000,'2025/1/1','2025/12/31')
,('CP02',3,'H',20000,'2025/1/1','2025/12/31')
,('CP03',1,'H',15000,'2025/1/1','2025/12/31')
;

-- 商品テーブル(設問に必要な項目に限定)
CREATE TABLE 商品 (
    商品番号      CHAR(4) PRIMARY KEY
  , 商品原価      NUMERIC
);

INSERT INTO 商品 VALUES
 ('S001',30)
,('S002',50)
,('S003',100)
;

-- 売上テーブル
CREATE TABLE 売上 (
    売上番号         CHAR(4) PRIMARY KEY
  , 店舗番号         CHAR(4)
  , 売上年月日       DATE
  , 会員番号         CHAR(4)
  , キャンペーン番号 CHAR(4) 
  , キャンペーン種別 CHAR(1) 
);

INSERT INTO 売上 VALUES
 ('U101','T111','2025/07/01','KA01','CP01','H')
,('U102','T111','2025/07/01','KA01','CP01','L')
,('U103','T222','2025/07/01','KA02','CP02','H')
,('U104','T222','2025/07/01','KA02','CP02','H')
;

-- 売上明細テーブル(設問に必要な項目に限定)
CREATE TABLE 売上明細 (
    売上番号         CHAR(4)
  , 売上明細番号     INTEGER
  , 商品番号         CHAR(4) REFERENCES 商品(商品番号)
  , 商品個数         NUMERIC
  , 商品単価         NUMERIC
  , PRIMARY KEY (売上番号 ,売上明細番号)
);

INSERT INTO 売上明細 VALUES
 ('U101',1,'S001',5,90)
,('U101',2,'S002',8,100)
,('U101',3,'S003',3,200)
,('U102',1,'S001',7,90)
,('U102',2,'S002',2,100)
,('U102',3,'S003',11,200)
,('U103',1,'S002',1,100)
,('U103',2,'S002',3,105)
,('U103',3,'S002',2,90)
,('U104',1,'S001',6,92)
,('U104',2,'S001',12,89)
,('U104',3,'S003',9,210)
;

問題文のSQL完成版

パラメータで指定するキャンペーン番号は、変えて試してみてください。

SELECT
     CK.キャンペーン種別
    ,COALESCE(UK.売上計,0) AS 売上計
    ,COALESCE(UK.原価計,0) AS 原価計
    ,COALESCE(UK.売上計,0) - COALESCE(UK.原価計,0) AS 粗利計
    ,CK.キャンペーン実施金額計
FROM
(
    SELECT
         キャンペーン種別
        ,SUM(キャンペーン実施金額) AS キャンペーン実施金額計
    FROM キャンペーン実施
    WHERE キャンペーン番号 = 'CP01' -- パラメータで指定する項目
    GROUP BY キャンペーン種別
) CK
LEFT OUTER JOIN
(
    SELECT
         U.キャンペーン種別
        ,SUM(M.商品個数 * M.商品単価) AS 売上計
        ,SUM(M.商品個数 * S.商品原価) AS 原価計
    FROM 売上 U
    INNER JOIN 売上明細 M ON U.売上番号 = M.売上番号
    INNER JOIN 商品 S ON M.商品番号 = S.商品番号
    WHERE U.キャンペーン番号 = 'CP01' -- パラメータで指定する項目
    GROUP BY U.キャンペーン種別
) UK
ON CK.キャンペーン種別 = UK.キャンペーン種別
;

さいごに

これで、設問2は終わりです。
前回と同じことですが、問題文の全体ではなくポイントだけ紹介しているので、分かり辛いところもあるかもしれません。

下記のコンテンツを合わせてご利用いただくことで、更に理解が深まると思います。

  • IPAの過去問を見ながら、本記事を読む。
  • 私の個人YouTubeの過去問解説をご視聴いただく(※毎回プレビュー載せるのも何なので、今回はリンクのみ)
  • 本記事でご紹介したSQLを動かしてみる。

そして、次回もSQLが続きます。

ここまでお付き合い頂き、ありがとうございましたm(_ _)m

Agent Grow Tech Notes
Agent Grow Tech Notes

Discussion