Question

J'ai deux tables et je souhaite 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, telle 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?

Était-ce utile?

La solution

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 de mon blog pour plus de détails sur les performances:

Malheureusement, MySQL n'autorise pas l'utilisation de la table cible dans une sous-requête dans une instruction UPDATE , vous devez donc vous en tenir à des solutions moins efficaces LEFT JOIN syntaxe.

Autres conseils

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ù 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 du 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`)
)
                DECLARE @cols VARCHAR(max),@colsUpd VARCHAR(max), @query VARCHAR(max),@queryUpd VARCHAR(max), @subQuery VARCHAR(max)
DECLARE @TableNameTest NVARCHAR(150)
SET @TableNameTest = @TableName+ '_Staging';
SELECT  @colsUpd = STUF  ((SELECT DISTINCT '], T1.[' + name,']=T2.['+name+'' FROM sys.columns
                 WHERE object_id = (
                                    SELECT top 1 object_id 
                                      FROM sys.objects
                                     WHERE name = ''+@TableNameTest+''
                                    )
                and name not in ('Action','Record_ID')
                FOR XML PATH('')
            ), 1, 2, ''
        ) + ']'


  Select @queryUpd ='Update T1
SET '+@colsUpd+'
FROM '+@TableName+' T1
INNER JOIN '+@TableNameTest+' T2
ON T1.Record_ID = T2.Record_Id
WHERE T2.[Action] = ''Modify'''
EXEC (@queryUpd)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top