【MySQL】レコードを、別テーブルの特定の値で UPDATE する方法

【MySQL】レコードを、別テーブルの特定の値で UPDATE する方法

この歳まで生きてきて「戻り梅雨」という概念をさっき初めて知った kimoto です。

データベースの情報をアップデートする際に、テーブルをまたがって行いたい時があります。 例えば A というテーブルのデータを B というテーブルの特定のデータに置き換える、とか。 UPDATE 文をいくつも書いてひとつひとつやる方法もあるし、スクリプトを書いてループで回すやり方もあるでしょう。
今日は、自分へのメモも兼ねて SQL 文だけで行うやり方を書いてみます。

TableA の値を TableB の値で更新する

まず、TabelA の内容を TableB の内容にする方法です。

例えば、TableA の name というフィールドの値を、TableB のうち同じ id を持つレコードの name で上書きしたいとします。
ちなみに、id は一意とう前提です。その場合、流す UPDATE 文は単純。

UPDATE TableA, TableB 
SET TableA.name = TableB.name 
WHERE TableA.id = TableB.id;

これで、同じ id のレコードの name で更新されました。

TableA に属する TableB の値を、TableA が属する TableC の値で更新する

次に応用編。見出しはちょっとわかりづらい表現になっちゃいました。

例えば、Users というテーブルがあり、そこの1レコードである User が所有する情報 Infos というテーブルがあるとします。そして逆に、 User が属する Companies というテーブルがあるとします。
それぞれの紐付けは Infos.user_id と Users.id 、Users.company_id と Companies.id という感じでつながってるとします。

130724_kimoto_01.png

この時に、Infos の name というフィールドを、所有者が所属している Companies の name で上書きしたい場合を考えます。

この場合、Infos と Companies の間に直接的な接点がないため、先ほどのような単純な文ではいけません。
しかし、先ほどの TableB の部分に SELECT 文を使って Infos.id と Companies.name の組み合わせ持ってくることで実現できます。

まずは準備としてデータ取得の SQL 文を考えてみます。

SELECT Infos.id AS id, Companies.name AS name
FROM Infos 
    LEFT JOIN Users ON Infos.user_id = Users.id
    LEFT JOIN Companies ON Users.company_id = Companies.id;

Infos、Users、Companies を JOIN でつなげて、Infos.id と Companies.name の組み合わせでデータを持ってきました。
では、これを先ほどの UPDATE 文に入れ込んでいきましょう。

UPDATE Infos,  (SELECT Infos.id AS id, Companies.name AS name FROM Infos LEFT JOIN Users ON Infos.user_id = Users.id LEFT JOIN Companies ON Users.company_id = Companies.id) AS Com
SET Infos.name = Com.name 
WHERE Infos.id = Com.id;

これで目的の上書きができました。

この、複数テーブルにまたがって UPDATE を行うやり方をついつい忘れがちなので、自分用も兼ねて書いてみました。
参考になれば幸いです。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ