理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

集合演算

集合演算を行うためには,その演算対象となる (複数の) テーブルが以下の制約を満たす必要がある.

  • 同数のカラムを持つ
  • テーブル間の各カラムのデータ型が同じか,あるいは型変換が可能

UNION ALL と UNION

和集合演算を行う UNION ですが,厳密には UNION ALL と UNION があるようです.この二つの違いは,重複を許すかどうかで,具体例を見た方がわかりやすそうですね.
こちらが UNION ALL.同じカラムが 2 つできています.

mysql> SELECT 1 num, 'abc' str
    -> UNION ALL
    -> SELECT 1 num, 'abc' str;
+-----+-----+
| num | str |
+-----+-----+
|   1 | abc |
|   1 | abc |
+-----+-----+
2 rows in set (0.00 sec)

UNION の場合は,同じカラムは作成されません.

mysql> SELECT 1 num, 'abc' str UNION SELECT 1 num, 'abc' str;
+-----+-----+
| num | str |
+-----+-----+
|   1 | abc |
+-----+-----+
1 row in set (0.00 sec)

INTERSECT,EXCEPT

ぼくが使っている MySQL

mysql> SELECT version();
+-----------+
| version() |
+-----------+
| 5.0.51b   |
+-----------+

なんだけど,どうも INTERSECT ができない.みんなこまらないのかなーと思ってたら,こんなエントリを発見する.

An INTERSECT is simply an inner join where we compare the tuples of one table with those of the other, and select those that appear in both while weeding out duplicates. So

SELECT member_id, name FROM a
INTERSECT
SELECT member_id, name FROM b

can simply be rewritten to

SELECT a.member_id, a.name
FROM a INNER JOIN b
USING (member_id, name)

http://www.bitbybit.dk/carsten/blog/?p=71

そうか,INNER JOIN でできるのか! ちなみにこのページには,EXCEPT (差集合) の方法も書いてある.

その他メモ

  • 集合演算を施した後のテーブルをソートするときの ORDER BY 句で指定するカラム名は,一番最初に作るテーブルのカラム名.二番目以降のテーブルのカラム名MySQL では認識しない.