2つのテーブルがあり、LEFT JOINのすべての行のT1のフィールドを更新したい。
簡単な例として、次の結果セットのすべての行を更新します。
SELECT T1.* FROM T1 LEFT JOIN T2 ON T1.id = T2.id WHERE T2.id IS NULL
MySQLマニュアル は次のように述べています:
複数テーブルのUPDATEステートメントでは、LEFT JOINなど、SELECTステートメントで許可されている任意のタイプの結合を使用できます。
しかし、文書化された複数テーブルの更新では、それを行うための適切な構文が見つかりません。
適切な構文は何ですか?
UPDATE t1
LEFT JOIN
t2
ON t2.id = t1.id
SET t1.col1 = newvalue
WHERE t2.id IS NULL
SELECT
の場合、NOT IN
/NOT EXISTS
構文を使用する方が効率的です。
SELECT t1.*
FROM t1
WHERE t1.id NOT IN
(
SELECT id
FROM t2
)
パフォーマンスの詳細については、私のブログの記事を参照してください。
LEFT JOIN
のパフォーマンスとNOT IN
の比較残念ながら、MySQL
では、UPDATE
ステートメントのサブクエリでターゲットテーブルを使用できません。そのため、効率の低いLEFT JOIN
構文に固執する必要があります。
同じことがデータが正規化されたシナリオにも適用できますが、今度は3番目のテーブルで見つかった値を持つテーブルが必要です。以下を使用すると、2番目のテーブルに好かれる3番目のテーブルの情報でテーブルを更新できます。
UPDATE t1
LEFT JOIN
t2
ON
t2.some_id = t1.some_id
LEFT JOIN
t3
ON
t2.t3_id = t3.id
SET
t1.new_column = t3.column;
これは、ユーザーとグループがあり、ユーザーにグループ名の独自のバリエーションを追加できるようにしたい場合に役立ちます。そのため、元々、ユーザーがいるフィールドに既存のグループ名をインポートする必要があります。変更できるようになります。
Table A
+--------+-----------+
| A-num | text |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
+--------+-----------+
Table B
+------+------+--------------+
| B-num| date | A-num |
| 22 | 01.08.2003 | 2 |
| 23 | 02.08.2003 | 2 |
| 24 | 03.08.2003 | 1 |
| 25 | 04.08.2003 | 4 |
| 26 | 05.03.2003 | 4 |
テーブルAのフィールドテキストを更新します
UPDATE `Table A`,`Table B`
SET `Table A`.`text`=concat_ws('',`Table A`.`text`,`Table B`.`B-num`," from
",`Table B`.`date`,'/')
WHERE `Table A`.`A-num` = `Table B`.`A-num`
そして、この結果に来ます:
Table A
+--------+------------------------+
| A-num | text |
| 1 | 24 from 03 08 2003 / |
| 2 | 22 from 01 08 2003 / |
| 3 | |
| 4 | 25 from 04 08 2003 / |
| 5 | |
--------+-------------------------+
ここでは、表Bの1つのフィールドのみが受け入れられますが、この結果になります。
Table A
+--------+--------------------------------------------+
| A-num | text |
| 1 | 24 from 03 08 2003 |
| 2 | 22 from 01 08 2003 / 23 from 02 08 2003 / |
| 3 | |
| 4 | 25 from 04 08 2003 / 26 from 05 03 2003 / |
| 5 | |
+--------+--------------------------------------------+
UPDATE `Table A` a
SET a.`text`=(
SELECT group_concat(b.`B-num`,' from ',b.`date` SEPARATOR ' / ')
FROM `Table B` b WHERE (a.`A-num`=b.`A-num`)
)