※そのうちちゃんと書くかも。とりあえずメモ書き。
※わかりやすいタイトル募集...。
やりたいこと
以下の様なテーブルがあるときに、テーブルAとテーブルBを比較して、テーブルAにしか無いレコードを抽出したい。
テーブル構成
- テーブルA(table_a)
- a_id
- a_name
- a_item_id
- a_code
- (↑ここにはb_x, b_y, b_zを単純に結合した文字列が入っている。)
- テーブルB(table_b)
- b_id
- b_item_name
- b_item_no
- b_x
- b_y
- b_z
答え
その1
-
outer join
を使って、くっつけた側のレコードがnullでは無いものを取り出す。-
left outer join
なら、くっつけた側(join句の方)のレコードが存在しないレコードが取れる。 -
right outer join
なら、くっつけられた側(from句の方)が存在しないレコードが取れる。 -
full outer join
はMySQLだと対応してないけど、くっつけた側にしか無いレコードもくっつけられた側にしか無いレコードも両方取れるらしい。 - ※ところで
outer
って書いても書かなくても同じ?
-
- on句の条件で
concat
を使って、カラムの値をくっつける。-
||(パイプ)
を使っても良い。但し設定次第ではパイプが使えないこともあるらしい。
-
SELECT
*
FROM
table_a
LEFT OUTER JOIN
table_b
ON
(a_item_id = b_item_no and a_code = concat(b_x, b_y, b_z))
WHERE
b.item_no IS NULL;
たぶんこんな感じ。
その2
単純に「table_aにしかないデータを取りたい」のなら、
exists
句を使うのはどうですか?
(元が SELECT * なので、not existsにすると結果セットにtable_bのカラムが出てきませんが……)
と教えていただきました!
SELECT
*
FROM
table_a
WHERE
NOT EXISTS (
SELECT
NULL
FROM
table_b
WHERE
a_item_id = b_item_no
and a_code = concat(b_x, b_y, b_z)
)
;
なるほど、こういう方法もあるのですね!
ありがとうございます!
(もっと勉強せねば...。)