LoginSignup
12
11

More than 5 years have passed since last update.

テーブルの比較で、カラムの値を結合して比較

Last updated at Posted at 2014-11-26

※そのうちちゃんと書くかも。とりあえずメモ書き。
※わかりやすいタイトル募集...。

やりたいこと

以下の様なテーブルがあるときに、テーブル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

Facebook経由

単純に「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)
  )
;

なるほど、こういう方法もあるのですね!
ありがとうございます!

(もっと勉強せねば...。)

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11