🙄
【PostgreSQL】EXISTS・NOT EXISTSについて
準備
classes
class_id | class_name |
---|---|
1 | 1年A組 |
2 | 1年B組 |
3 | 2年A組 |
4 | 2年B組 |
students
student_id | student_name | class_id |
---|---|---|
1 | 田中 太郎 | 1 |
2 | 佐藤 花子 | 1 |
3 | 鈴木 一郎 | 2 |
4 | 山田 次郎 | 3 |
CREATE TABLE classes (
class_id SERIAL PRIMARY KEY,
class_name VARCHAR(50) NOT NULL
);
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
student_name VARCHAR(100) NOT NULL,
class_id INT REFERENCES classes(class_id) ON DELETE CASCADE
);
-- クラスの追加
INSERT INTO classes (class_name) VALUES
('1年A組'),
('1年B組'),
('2年A組'),
('2年B組');
-- 生徒の追加
INSERT INTO students (student_name, class_id) VALUES
('田中 太郎', 1), -- 1年A組
('佐藤 花子', 1), -- 1年A組
('鈴木 一郎', 2), -- 1年B組
('山田 次郎', 3); -- 2年A組
-- 2年B組には生徒を登録しない(NOT EXISTS のテスト用)
EXISTSとは
データが存在するかどうかをチェックするSQLのしくみ
- データが 1行でもあるなら「YES」(=条件が満たされる)
- 1行もないなら「NO」(=条件が満たされない)
使用例
生徒が1人以上いるクラスを取得(2年B組は除外される)
SELECT * FROM classes c
WHERE EXISTS (
SELECT * FROM students s
WHERE s.class_id = c.class_id
);
処理の流れ
1.メインクエリがclassesテーブルのデータを1行ずつ取得するので、最初の行が取得される
class_id | class_name |
---|---|
1 | 1年A組 |
2.サブクエリを実行
生徒が1人以上いる→YES
3.上記2.でYESになったので結果に含める
4.classesテーブルの次の行を取得し上記の手順で調べる
class_id | class_name |
---|---|
2 | 1年B組 |
5.同じようにclassesテーブルのデータを1行ずつ取得しながら調べる
→データがない場合(2年B組)だけ「NO」になる!
class_id | class_name | サブクエリの結果 |
---|---|---|
1 | 1年A組 | YES✅ |
2 | 1年B組 | YES✅ |
3 | 2年A組 | YES✅ |
4 | 2年B組 | No❌ |
NOT EXISTSとは
データが存在しないことをチェックするSQLのしくみ
使用例
「生徒がいないクラス」を取得
SELECT * FROM classes c
WHERE NOT EXISTS (
SELECT * FROM students s
WHERE s.class_id = c.class_id
);
<出力例>
処理の流れ
1.メインクエリがclassesテーブルのデータを1行ずつ取得するので、最初の行が取得される
class_id | class_name |
---|---|
1 | 1年A組 |
2.サブクエリを実行
生徒が1人以上いる→NO(データが存在しない場合YESになる)
3.上記2.で生徒が1人以上いたので結果にこの行は含めない
4.classesテーブルの次の行を取得し同じように調べる
class_id | class_name |
---|---|
2 | 1年B組 |
5.同じようにclassesテーブルのデータを1行ずつ取得しながら調べる
6.クラスID4のデータを同じように調べた時、生徒が1人もいない→YESなので、結果にこの行を含める
class_id | class_name | サブクエリの結果 |
---|---|---|
1 | 1年A組 | No❌ |
2 | 1年B組 | No❌ |
3 | 2年A組 | No❌ |
4 | 2年B組 | YES✅ |
Udemyで講座を公開中!
X(旧Twitter)
Zenn 本
Youtube
Discussion