概要
SQLパズル11 テストの解法2についてのメモです。
題材としては、Having句を使った関係除算です。
要件
テスト結果に関したテーブルがある。
テストが完了している場合、日付が記入される
テストが完了していない場合、日付は記入されておらず nullが記入される
テストが全て完了している科目のみを取得したい。
DDL
drop table if EXISTS TestResults;
create table TestResults(
test_name CHAR(20) not null,
test_step integer not null,
comp_date Date,
primary key(test_name,test_step)
);
INSERT INTO TestResults VALUES('読解', 1, '2006-03-10');
INSERT INTO TestResults VALUES('読解', 2, '2006-03-12');
INSERT INTO TestResults VALUES('数学', 1, NULL);
INSERT INTO TestResults VALUES('数学', 2, '2006-03-12');
INSERT INTO TestResults VALUES('化学', 1, '2006-03-08');
INSERT INTO TestResults VALUES('化学', 2, '2006-03-12');
INSERT INTO TestResults VALUES('化学', 3, '2006-03-15');
答え
SELECT test_name
FROM TestResults
GROUP BY test_name
HAVING COUNT(*) = COUNT(comp_date)
;
経過
sql
--test_name毎に部分集合を作る
SELECT test_name,count(*) as C_aster, count(comp_date) as C_comp_date
FROM TestResults
GROUP BY test_name
;
-- Having句で部分集合の条件を指定する
-- cout(*)がnullを数えるに対して、COUNT(comp_date)はnullを数えないことを利用している。
SELECT test_name,count(*) as C_aster, count(comp_date) as C_comp_date
FROM TestResults
GROUP BY test_name
HAVING COUNT(*) = COUNT(comp_date)
;
図
参考
SQLパズル p88
SQLパズル サポートページ
https://mickindex.sakura.ne.jp/database/db_support_sqlpuzzle.html#LocalLink-p20
達人に学ぶSQL徹底指南書第2版 p133 column 関係除算
関係除算の定義が複数ある
達人に学ぶSQL徹底指南書第2版 p127 バスケット解析
github 差分
https://github.com/RYA234/SQL_Puzzle_Learning/commit/71ce75de6a6ac469009b738a56e35f8765e196fc