2
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パズル4 入館証 解法1 メモ

Last updated at Posted at 2024-10-30

概要

SQLパズル4入館証 のp18 の 解法1の学習メモです。
テーマとしては、自己結合の使い方が肝です。

設問

・社員は現在働いてる職場に応じて、複数の入館証を持つことができる。
・同時に有効な入館証は一つだけ
・有効な入館証は 新しい職場で発行された入館証とする。

SQL

DDL

DROP TABLE IF EXISTS personnel CASCADE;
CREATE TABLE personnel
(
    emp_id integer PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL
);

Insert  Into personnel values
(1,'John'),
(2,'Mary'),
(3,'Bill'),
(4,'Mike')
;


DROP TABLE IF EXISTS badges CASCADE;
CREATE TABLE Badges
(badge_nbr INTEGER NOT NULL PRIMARY KEY,
 emp_id INTEGER NOT NULL,
 issued_date DATE NOT NULL,
 badge_status CHAR(1) NOT NULL
    CHECK (badge_status IN ('A', 'I')));



INSERT INTO Badges VALUES(100, 1, '2007-01-01', 'I');
INSERT INTO Badges VALUES(200, 1, '2007-02-01', 'I');  --社員1番の最新バッジ
INSERT INTO Badges VALUES(300, 2, '2007-03-01', 'I');  --社員2番の最新バッジ
INSERT INTO Badges VALUES(400, 3, '2007-03-01', 'I');  
INSERT INTO Badges VALUES(500, 3, '2007-04-01', 'I');  
INSERT INTO Badges VALUES(600, 3, '2007-05-01', 'I');  --社員3番の最新バッジ
INSERT INTO Badges VALUES(800, 4, '2007-07-01', 'I');  
INSERT INTO Badges VALUES(900, 4, '2007-08-01', 'A');  --社員4番の最新バッジ

答えのSQL

-- Update Badges
--     SET badge_status = 'A'
    SELECT * 
    FROM Badges
    WHERE ('I' = ALL (SELECT badge_status   --イの条件
                        FROM Badges AS B1
                        WHERE Badges.emp_id = B1.emp_id))
    AND (issued_date = (SELECT MAX(issued_date) -- ロの条件
                            FROM Badges AS B2
                        WHERE Badges.emp_id = B2.emp_id));

image.png

分解して考える

イ の条件

①にemp_idに対して、badge_statusの組み合わせを自己結合を使って求める。
②限定術後のALLを使って、全てのレコードがbadge_status='I'であるemp_idを割り出す。

sql

-- ①組み合わせを求める
SELECT B1.*,B2.*
FROM Badges AS B1, Badges AS B2
WHERE B2.emp_id = B1.emp_id;

-- ②emp_idでB2の全てのbadge_statusが'I'のレコードのみを取得する。
SELECT B2.*
FROM Badges AS B2
WHERE
('I' = ALL (SELECT B2.badge_status
              FROM Badges AS B1
              WHERE B2.emp_id = B1.emp_id));

image.png

ロ の条件

sql

①にemp_idに対して、issued_dateの組み合わせを自己結合を使って求める。
②限定術後のALLを使って、全てのレコードがbadge_status='I'であるemp_idを割り出す。

-- ①emp_idに対して、issued_dateの組み合わせを求める
SELECT B1.emp_id,B1.issued_date
    FROM Badges AS B2,Badges AS B1
	WHERE B1.emp_id = B2.emp_id;

-- ② ①で求めたissued_dateの組み合わせの内最大値を求める。
SELECT * 
FROM Badges AS B1
WHERE
(B1.issued_date = (SELECT MAX(B2.issued_date)
                        FROM Badges AS B2
                        WHERE B1.emp_id = B2.emp_id));

image.png

イ AND ロ

SQL

SELECT * 
FROM Badges
WHERE
('I' = ALL (SELECT badge_status
              FROM Badges AS B1
              WHERE Badges.emp_id = B1.emp_id))
AND
(issued_date = (SELECT MAX(issued_date)
                            FROM Badges AS B2
                        WHERE Badges.emp_id = B2.emp_id));

image.png

参考

SQLパズル p18

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

達人に学ぶSQL徹底指南書第2版 p44 自己結合の使い方 組み合わせ
達人に学ぶSQL徹底指南書第2版 p53 まとめ参考書籍

2
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
2
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?