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パズル 45 ペパロニピザ その2の解法メモ

Last updated at Posted at 2024-11-10

概要

SQLパズル p189 45 ペパロニピザ その2の解法メモです。
CASE式と集約関数(SUM)の使用方法が肝ですね。

要件 

行→列に変換したい。
範囲指定した値毎に列に配置したい。
a,b,c(a<b<c)の数字に対して
0<値<aの場合 1列目
a<値<bの場合 2列目
b<値<cの場合 3列目
値>cの場合  4列目

今回の場合は以下とする。
a=30 b=60 c=90
値=現在の日付と過去の日付の差
現在の日付は20070601とする

image.png

SQL

DDL


DROP TABLE IF EXISTS FriendsofPepperoni;
--重複行があるというので、主キーなし
CREATE TABLE FriendsofPepperoni
(cust_id INTEGER,
 bill_date DATE,
 pizza_amt DECIMAL(5,2));

--答え3用マスタテーブル
DROP TABLE IF EXISTS ReportRanges;
CREATE TABLE ReportRanges
(day_count CHAR(32), 
 start_cnt INTEGER, 
 end_cnt   INTEGER);

INSERT INTO FriendsofPepperoni VALUES(1, '2007-05-07', 10);
INSERT INTO FriendsofPepperoni VALUES(1, '2007-04-01', 20);
INSERT INTO FriendsofPepperoni VALUES(1, '2007-03-01', 30);
INSERT INTO FriendsofPepperoni VALUES(1, '2007-01-01', 40);
INSERT INTO FriendsofPepperoni VALUES(2, '2007-05-06', 50);
INSERT INTO FriendsofPepperoni VALUES(2, '2007-04-01', 60);
INSERT INTO FriendsofPepperoni VALUES(2, '2007-03-01', 70);
INSERT INTO FriendsofPepperoni VALUES(2, '2007-01-01', 80);

--答え3用
INSERT INTO ReportRanges VALUES('under Thirty days', 00, 30);
INSERT INTO ReportRanges VALUES('Sixty days', 31, 60);
INSERT INTO ReportRanges VALUES('Ninty days', 61, 90);


答えのSQL

-- その2答え
-- case式を使用
SELECT cust_id,
        SUM(CASE WHEN bill_date
                       BETWEEN cast( '20070601' as date )  - INTERVAL '30' DAY
                            AND cast( '20070601' as date )
                       THEN pizza_amt ELSE 0.00 END) AS age1,
        SUM(CASE WHEN bill_date
                      BETWEEN cast( '20070601' as date ) - INTERVAL '60' DAY
                            AND cast( '20070601' as date ) - INTERVAL '31' DAY
                        THEN pizza_amt ELSE 0.00 END) AS age2,
        SUM(CASE WHEN bill_date
                      BETWEEN cast( '20070601' as date )- INTERVAL '90' DAY
                            AND cast( '20070601' as date ) - INTERVAL '61' DAY
                      THEN pizza_amt ELSE 0.00 END) AS age3,
        SUM(CASE WHEN bill_date < cast( '20070601' as date )  - INTERVAL '91' DAY
                      THEN pizza_amt ELSE 0.00 END) AS age4
        FROM FriendsOfPepperoni
        GROUP BY cust_id
        ORDER BY cust_id;

-- 各テーブルがどのageに分類されるか確認する
SELECT *,(cast( '20070601' as date ) - bill_date) as diff
	,CASE WHEN cast( '20070601' as date ) - bill_date BETWEEN '0'  AND '30' THEN 'age1'
		  WHEN cast( '20070601' as date ) - bill_date BETWEEN '31'  AND '60' THEN 'age2'
	 	  WHEN cast( '20070601' as date ) - bill_date BETWEEN '61'  AND  '90' THEN 'age3'
		  WHEN cast( '20070601' as date ) - bill_date > '91' THEN 'age4'
		  ELSE '' END
FROM FriendsOfPepperoni;


参考

SQLパズル p190 45 ペパロニピザ

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

達人に学ぶSQL徹底指南書第2版 p4 CASE式の真価は他のSQLのツールと組み合わせた時に発揮する。
達人に学ぶSQL徹底指南書第2版 p8 CASE 異なる条件の集計を一つのSQLで行う

github 差分
https://github.com/RYA234/SQL_Puzzle_Learning/commit/2086254c0a40f6ed924586d41d606db3938bfa2e

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?