J'ai deux tables et je veux mettre à jour les champs dans T1 pour toutes les lignes d'un LEFT JOIN.
Pour un exemple simple, mettez à jour toutes les lignes de l'ensemble de résultats suivant:
SELECT T1.* FROM T1 LEFT JOIN T2 ON T1.id = T2.id WHERE T2.id IS NULL
Le manuel MySQL indique que:
Les instructions UPDATE à tables multiples peuvent utiliser tout type de jointure autorisée dans les instructions SELECT, telles que LEFT JOIN.
Mais je ne trouve pas la syntaxe appropriée pour cela dans la documentation UPDATE à tables multiples documentée.
Quelle est la syntaxe appropriée?
UPDATE t1
LEFT JOIN
t2
ON t2.id = t1.id
SET t1.col1 = newvalue
WHERE t2.id IS NULL
Notez que pour un SELECT
il serait plus efficace d'utiliser la syntaxe NOT IN
/NOT EXISTS
:
SELECT t1.*
FROM t1
WHERE t1.id NOT IN
(
SELECT id
FROM t2
)
Voir l'article sur mon blog pour plus de détails sur les performances:
LEFT JOIN
par rapport à NOT IN
Malheureusement, MySQL
ne permet pas d'utiliser la table cible dans une sous-requête dans une instruction UPDATE
. C'est pourquoi vous devrez vous en tenir à la syntaxe moins efficace LEFT JOIN
.
La même chose peut être appliquée à un scénario où les données ont été normalisées, mais maintenant vous voulez que les valeurs d'une table soient trouvées dans une troisième table. Ce qui suit vous permettra de mettre à jour une table avec les informations d'une troisième table qui est appréciée par une deuxième table.
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;
Cela serait utile dans le cas où vous auriez des utilisateurs et des groupes et que vous souhaitiez qu'un utilisateur puisse ajouter sa propre variante du nom du groupe. Par conséquent, vous voudriez à l'origine importer les noms de groupes existants dans le champ où se trouve l'utilisateur. va pouvoir le modifier.
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 |
Je mettrai à jour le texte de champ dans le tableau A avec
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`
et arriver à ce résultat:
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 | |
--------+-------------------------+
où un seul champ de la table B est accepté, mais je vais arriver à ce résultat:
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`)
)