1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQLパズル pp174 41 予算 解法その1 学習メモ

Posted at

概要

SQLパズル pp174 41 予算の解法その1のメモです。
問題の肝は CASE式と 一行目のSELECT文の役割(重要)です。

要件

・商品番号毎のの説明(item_descr),購入額の合計(actual_tot),見積もり金額の合計(estimated_tot)、請求書番号を取得する。
・購入額の合計はActualテーブルのactual_amtの合計額
・見積もり金額の合計はEstimatesテーブルのestimated_amtの合計額
・請求書番号が2種類ある場合は mixと表示する

※tot totalの略語らしい (いうほど略してるか?)

image.png

SQL

DDL

DROP TABLE IF EXISTS Items;
CREATE TABLE Items
(item_nbr INTEGER,
 item_descr CHAR(10));

DROP TABLE IF EXISTS Actuals;
CREATE TABLE Actuals
(item_nbr   INTEGER, 
 actual_amt DECIMAL(5,2),
 check_nbr  CHAR(4));

DROP TABLE IF EXISTS Estimates;
CREATE TABLE Estimates
(item_nbr      INTEGER, 
 estimated_amt DECIMAL(5,2));

INSERT INTO Items VALUES(10, 'Item 10');
INSERT INTO Items VALUES(20, 'Item 20');
INSERT INTO Items VALUES(30, 'Item 30');
INSERT INTO Items VALUES(40, 'Item 40');
INSERT INTO Items VALUES(50, 'item 50');

INSERT INTO Actuals VALUES(10, 300.00, '1111');
INSERT INTO Actuals VALUES(20, 325.00, '2222');
INSERT INTO Actuals VALUES(20, 100.00, '3333');
INSERT INTO Actuals VALUES(30, 525.00, '1111');

INSERT INTO Estimates VALUES(10, 300.00);
INSERT INTO Estimates VALUES(10, 50.00);
INSERT INTO Estimates VALUES(20, 325.00);
INSERT INTO Estimates VALUES(20, 110.00);
INSERT INTO Estimates VALUES(40, 25.00);


答えのSQL

-- p174 41 予算 方法 その1
SELECT * FROM
    (SELECT I1.item_nbr,I1.item_descr,
        (SELECT SUM(A1.actual_amt)
            FROM Actuals AS A1
            WHERE I1.item_nbr = A1.item_nbr) AS tot_act,
        (SELECT SUM(E1.estimated_amt)
            FROM Estimates AS E1
            WHERE I1.item_nbr = E1.item_nbr) AS estimate_tot,
        (SELECT CASE WHEN COUNT(*) = 1
                     THEN MAX(check_nbr)
                     ELSE 'Mixed' END
                FROM  Actuals AS A2
                WHERE I1.item_nbr = A2.item_nbr
                GROUP BY item_nbr) AS check_nbr
FROM Items I1) AS TMP
WHERE tot_act IS NOT NULL
    OR estimate_tot IS NOT NULL;

-- CASE部分がある呼ぶクエリのみ抜粋
-- item_nbr=40 50 は存在しない、他のサブクエリと結合すると、case部分の値はnullとなる
SELECT I1.item_nbr,MIN(check_nbr) as check_nbr_first,MAX(check_nbr) as check_nbr_second,
	CASE WHEN COUNT(*) = 1
                     THEN MAX(check_nbr)
                     ELSE 'Mixed' END
                FROM  Actuals AS A2,Items AS I1
                WHERE I1.item_nbr = A2.item_nbr
                GROUP BY I1.item_nbr
;
-- 最初のFROM句以下の内容
SELECT I1.item_nbr,I1.item_descr,
	(SELECT SUM(A1.actual_amt)
		FROM Actuals AS A1
		WHERE I1.item_nbr = A1.item_nbr) AS tot_act,
	(SELECT SUM(E1.estimated_amt)
		FROM Estimates AS E1
		WHERE I1.item_nbr = E1.item_nbr) AS estimate_tot,
	(SELECT CASE WHEN COUNT(*) = 1
				 THEN MAX(check_nbr)
				 ELSE 'Mixed' END
			FROM  Actuals AS A2
			WHERE I1.item_nbr = A2.item_nbr
			GROUP BY item_nbr) AS check_nbr
	FROM Items I1
	-- この時点では、SELECT句になっておりFROM句の内容ではないので、WHERE句を使えない
	-- WHERE句で条件指定するためFROM句のサブクエリとして使っている
	-- WHERE tot_act IS NOT NULL -- エラーになる。FROMのテーブルにtot_actがないため
	--  OR estimate_tot IS NOT NULL -- エラーになる FROMのテーブルにtot_actがないため
		;
-- 答えのSQLからWHERE式を取り除いた部分
--  FROM句のサブクエリと同じ結果になることを確認できる。
SELECT * FROM
    (SELECT I1.item_nbr,I1.item_descr,
        (SELECT SUM(A1.actual_amt)
            FROM Actuals AS A1
            WHERE I1.item_nbr = A1.item_nbr) AS tot_act,
        (SELECT SUM(E1.estimated_amt)
            FROM Estimates AS E1
            WHERE I1.item_nbr = E1.item_nbr) AS estimate_tot,
        (SELECT CASE WHEN COUNT(*) = 1
                     THEN MAX(check_nbr)
                     ELSE 'Mixed' END
                FROM  Actuals AS A2
                WHERE I1.item_nbr = A2.item_nbr
                GROUP BY item_nbr) AS check_nbr
FROM Items I1) AS TMP;

image.png

参考

SQLパズル p174 予算 41 解法その1

SQLパズル サポートページ
https://mickindex.sakura.ne.jp/database/db_support_sqlpuzzle.html#LocalLink-p41

達人に学ぶSQL徹底指南書第2版 p18 CASE式の中で集約関数を使う

github 差分

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?