【SQL】関係演算 / 集合論

■ はじめに

SQL で前から集合ってことは知っていたが、
「基本がわかるSQL入門」って本で、
ちゃんと書かれていたので、メモ。

目次

【1】和(union)
【2】差(difference)
【3】共通(intersection)
【4】直積(direct product)
【5】選択(selection)
【6】射影(projection)
【7】結合(Join)
【8】商(division)

【1】和(union)

* 2つ又は3つ以上の集合の全要素を集めること

1)SQL

* 和演算は、UNIONを使う
* 重複行をそのまま残す場合は、UNION ALL

2)サンプル

SELECT name, tel FROM user
UNION
SELECT name, tel FROM staff
;

【2】差(difference)

* 2つの集合で、
 1つ目の集合にはあるけど、
 2つ目の集合にはない

1)SQL

* 差演算は、EXCEPT を使う
* 重複行をそのまま残す場合は、EXCEPT ALL

EXCEPT非対応DBの場合

* MySQLなど、EXCEPT / EXCEPT ALL がないDBの場合
 => 外部結合 又は サブクエリを使う

2)サンプル

SELECT name, tel FROM user
EXCEPT
SELECT name, tel FROM staff
;

EXCEPT非対応DBの場合

-- 外部結合
SELECT u.name, u.tel FROM user as u
LEFT OUT JON staff as s
 ON u.name = s.name AND u.tel = s.tel
WHERE s.name IS NULL;

-- サブクエリ
SELECT u.name, u.tel FROM user as u
WHERE NOT EXISTS (
  SELECT * FROM staff as s
  WHERE u.name = s.name AND u.tel = s.tel
);

【3】共通(intersection)

* 2つ又は3つ以上の集合で、同じ要素を求める

1)SQL

* INTERSECT を使う
* 重複行をそのまま残す場合は、INTERSECT ALL

INTERSECT 非対応DBの場合

* 内部結合やサブクエリを使用

2)サンプル

SELECT name, tel FROM user
INTERSECT 
SELECT name, tel FROM staff
;

【4】直積(direct product)

* 2つ又は3つ以上の集合を掛け合わせる

1)SQL

* CROSS JOIN を置かう

CROSS JOIN 非対応DBの場合

* FROM句に複数テーブルを指定し
 結合条件を書かなければいい

2)サンプル

SELECT * FROM student CROSS JOIN subject;

-- FROM句に複数テーブルを指定
SELECT * FROM student, subject;

【5】選択(selection)

* ある条件を満足させる行を選び取る場合

1)SQL

* WHEREを使う(そんだけ)

2)サンプル

SELECT * FROM staff WHERE name='Mike';

【6】射影(projection)

* 属性の部分集合から別の表を作ること

1)SQL

* SELECT句で列を指定する(そんだけ)

2)サンプル

SELECT name FROM staff;

【7】結合(Join)

* 一方の表が他方の表を完全に含む要素だけを取り出す演算

1)SQL

* INNER JOINを使う(そんだけ)

2)サンプル

SELECT * FROM user as u
INNER JOIN staff as s
ON u.id = s.id
;

【8】商(division)

* 一方の表が他方の表を完全に含む要素だけを取り出す演算

1)SQL

* サブクエリを2つ組み合わせて実現

関連記事

SQLを書くコツ
https://dk521123.hatenablog.com/entry/2016/01/11/173055
相関サブクエリ / 自己相関サブクエリ
https://dk521123.hatenablog.com/entry/2016/01/23/230608
差集合 ~ EXCEPT / MINUS etc ~
https://dk521123.hatenablog.com/entry/2021/05/26/142059
Window関数 ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/02/22/000000