プログラマメモ2 - programmer no memo2

LEFT -RIGHT - 外部結合で集合演算だそうです。 2012/11/17

SQLです。
やはりSQLは苦手です。ジョインとかインナージョインとかアウタージョインとかいうフレーズが聞こえると身構えてしまいます。...

差集合を求めるSQLです。
外部結合を使って差をもとめます。
LEFT側が大きい集合を想定しています。
LEFT - RIGHT = その差
というイメージしています。

用意するテーブルは以下
drop table a;
create table a (
  id          smallint unsigned not null auto_increment primary key
)
;
drop table b;
create table b (
  id          smallint unsigned not null auto_increment primary key
)
;

まず、aテーブルの状態

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
つぎにbテーブルの状態

+----+
| id |
+----+
|  1 |
|  3 |
|  5 |
|  6 |
|  7 |
|  8 |
+----+

外部結合してみます。
aテーブルを左におきます。
こんな感じのSQLにしてみました。

SELECT l.id, r.id
FROM
( -- LEFT
SELECT * FROM a
) l
LEFT OUTER JOIN
( -- RIGHT
SELECT * FROM b
) r
ON l.id = r.id
;
 結果は、

+----+------+
| id | id   |
+----+------+
|  1 |    1 |
|  2 | NULL |
|  3 |    3 |
|  4 | NULL |
|  5 |    5 |
|  6 |    6 |
+----+------+
ここから本題
右側にないものはNULLとなる性質を利用して、NULLであるものだけを残せば、結果として、差がとれるということのようですね。
使うSQLは以下

SELECT l.id, r.id
FROM
( -- LEFT
SELECT * FROM a
) l
LEFT OUTER JOIN
( -- RIGHT
SELECT * FROM b
) r
ON l.id = r.id
WHERE
r.id IS NULL
;
結果はこんな感じ

+----+------+
| id | id   |
+----+------+
|  2 | NULL |
|  4 | NULL |
+----+------+

: