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パズル 21  飛行機と飛行士の解法その2 メモ

Last updated at Posted at 2024-10-29

概要

SQLパズル 21  飛行機と飛行士の解法その2について

Having句を使った関係除算の理解が必要です。

要件

待機中の飛行機すべてを操縦できるパイロットをすべて選択したい。

関係除算

関係演算R÷Sは、関係Rのうち関係Sの全ての項目を含む行の集合を返す演算です。

SQL

DDL

drop table if EXISTS PilotSkills;
drop table if EXISTS Hangar;

CREATE TABLE PilotSkills
(pilot CHAR(15) NOT NULL,
 plane CHAR(15) NOT NULL,
    PRIMARY KEY (pilot, plane));

CREATE TABLE Hangar
(plane CHAR(15) PRIMARY KEY);

INSERT INTO PilotSkills VALUES ('Celko', 'Piper Cub');
INSERT INTO PilotSkills VALUES ('Higgins', 'B-52 Bomber');
INSERT INTO PilotSkills VALUES ('Higgins', 'F-14 Fighter');
INSERT INTO PilotSkills VALUES ('Higgins', 'Piper Cub');
INSERT INTO PilotSkills VALUES ('Jones', 'B-52 Bomber');
INSERT INTO PilotSkills VALUES ('Jones', 'F-14 Bomber');
INSERT INTO PilotSkills VALUES ('Smith', 'B-1 Bomber');
INSERT INTO PilotSkills VALUES ('Smith', 'B-52 Bomber');
INSERT INTO PilotSkills VALUES ('Smith', 'F-14 Fighter');
INSERT INTO PilotSkills VALUES ('Wilson', 'B-1 Bomber');
INSERT INTO PilotSkills VALUES ('Wilson', 'B-52 Bomber');
INSERT INTO PilotSkills VALUES ('Wilson', 'F-14 Fighter');
INSERT INTO PilotSkills VALUES ('Wilson', 'F-17 Fighter');
INSERT INTO PilotSkills VALUES ('KIRIKO', 'F-17 Fighter');

INSERT INTO Hangar VALUES ('B-1 Bomber');
INSERT INTO Hangar VALUES ('B-52 Bomber');
INSERT INTO Hangar VALUES ('F-14 Fighter');

答えのSQL

SELECT Pilot
  FROM PilotSkills AS PS1, Hangar AS H1
 WHERE PS1.plane = H1.plane
 GROUP BY PS1.pilot
HAVING COUNT(PS1.plane) = (SELECT COUNT(*) FROM Hangar)	
;

image.png

分解して考える

PilotSkillsとHangerのすべての組み合わせを求めた後、
PilotSkillsとHangerのplaneが合致する条件のみを取得する。

この時点で、Celkoは以下理由のため弾かれる
HangerにあるPlaneには乗れないため

sql

-- 1 PilotSKillsとHangerのすべての組み合わせを求める
SELECT PS1.*,H1.*
FROM PilotSkills AS PS1, Hangar AS H1
;

-- 2 
SELECT PS1.*,H1.*
  FROM PilotSkills AS PS1, Hangar AS H1
 WHERE PS1.plane = H1.plane
;

image.png

イで求めたレコードをGroup byとHaving句を使って条件指定する。
Hangerの件数と、pilotのplaneの件数を合致しているパイロットを取得する。

HigginsとJonesとKIRIKOは以下理由で弾かれる。
Hangerの総件数(=3)と同じ値にならないため。

結果、SmithとWillsonのみが残る。

sql

-- 2
SELECT PS1.*,H1.*
  FROM PilotSkills AS PS1, Hangar AS H1
 WHERE PS1.plane = H1.plane
;

-- 3
SELECT Pilot
  FROM PilotSkills AS PS1, Hangar AS H1
 WHERE PS1.plane = H1.plane
 GROUP BY PS1.pilot
HAVING COUNT(PS1.plane) = (SELECT COUNT(*) FROM Hangar)	
;

image.png

一言

数の除算は数を割るだけで一発で処理できる分、
関係除算(というか集合の除算??)は計算するのに数ステップ要るからややこしい。

参考

SQLパズル p91

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

達人に学ぶSQL徹底指南書第2版 p133 column 関係除算
関係除算の定義が複数ある

達人に学ぶSQL徹底指南書第2版 p127 バスケット解析

github コミット分
https://github.com/RYA234/SQL_Puzzle_Learning/commit/9a3690b4e91057cb23ed96ef856c4cfa02baa3dc

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?