トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
9-64 厳密な関係除算
SQLパズル
工場テーブル 操縦士テーブル
飛行機名 操縦士ID 操縦可能機
-------- -------- ----------
ジャビィ 1 ジャビィ
ハンター 2 ファルコ
ファルコ 3 ハンター
4 ジャビィ
4 ファルコ
5 ジャビィ
5 ハンター
5 ファルコ
5 ペリカン
6 ハンター
6 ペリカン
7 ジャビィ
7 ファルコ
7 ペリカン
8 ジャビィ
8 ハンター
8 ファルコ
工場テーブルにある全ての飛行機のみを操縦できる操縦士IDと、操縦可能機を出力する。
出力結果
操縦士ID 飛行機名
-------- ----------
8 ジャビィ
8 ハンター
8 ファルコ
9-9 差集合が空集合かチェックのアレンジ問題です
データ作成スクリプト
create table 工場(飛行機名 char(8));
insert into 工場 values('ジャビィ');
insert into 工場 values('ハンター');
insert into 工場 values('ファルコ');
create table 操縦士(
操縦士ID number(1),
操縦可能機 char(8));
insert into 操縦士 values(1,'ジャビィ');
insert into 操縦士 values(2,'ファルコ');
insert into 操縦士 values(3,'ハンター');
insert into 操縦士 values(4,'ジャビィ');
insert into 操縦士 values(4,'ファルコ');
insert into 操縦士 values(5,'ジャビィ');
insert into 操縦士 values(5,'ハンター');
insert into 操縦士 values(5,'ファルコ');
insert into 操縦士 values(5,'ペリカン');
insert into 操縦士 values(6,'ハンター');
insert into 操縦士 values(6,'ペリカン');
insert into 操縦士 values(7,'ジャビィ');
insert into 操縦士 values(7,'ファルコ');
insert into 操縦士 values(7,'ペリカン');
insert into 操縦士 values(8,'ジャビィ');
insert into 操縦士 values(8,'ハンター');
insert into 操縦士 values(8,'ファルコ');
commit;
SQL
--■■■not existsを使う方法■■■
select a.操縦士ID,a.操縦可能機
from 操縦士 a
where not exists(select b.操縦可能機,count(*) over()
from 操縦士 b
where b.操縦士ID = a.操縦士ID
minus
select c.飛行機名,count(*) over()
from 工場 c)
order by a.操縦可能機;
--■■■内部結合を使う方法■■■
select 操縦士ID,操縦可能機
from (select b.操縦士ID,b.操縦可能機,BeforeCount1,BeforeCount2,
count(*) over(partition by 操縦士ID) as AfterCount
from (select 飛行機名,count(*) over() as BeforeCount1
from 工場) a,
(select 操縦士ID,操縦可能機,
count(*) over(partition by 操縦士ID) as BeforeCount2
from 操縦士) b
where a.飛行機名 = b.操縦可能機)
where AfterCount = all(BeforeCount1,BeforeCount2)
order by 操縦可能機;
解説
内部結合を使う方法が、面白いと思います。