2009-04-30 53 views
145

Tengo dos tablas, y quiero actualizar campos en T1 para todas las filas en un LEFT JOIN.ACTUALIZA varias tablas en MySQL usando LEFT JOIN

Para un ejemplo sencillo, actualizar todas las filas de la siguiente conjunto de resultados:

SELECT T1.* FROM T1 LEFT JOIN T2 ON T1.id = T2.id WHERE T2.id IS NULL 

Los MySQL manual establece que:

UPDATE para múltiples tablas pueden utilizar cualquier tipo de join permitido por Sentencias SELECT, como LEFT JOIN.

Pero no encuentro la sintaxis adecuada para hacerlo en las tablas múltiples actualizadas UPDATE.

¿Cuál es la sintaxis correcta?

Respuesta

267
UPDATE t1 
LEFT JOIN 
     t2 
ON  t2.id = t1.id 
SET  t1.col1 = newvalue 
WHERE t2.id IS NULL 

Tenga en cuenta que para una SELECT sería más eficiente usar NOT IN/NOT EXISTS sintaxis:

SELECT t1.* 
FROM t1 
WHERE t1.id NOT IN 
     (
     SELECT id 
     FROM t2 
     ) 

Ver el artículo en mi blog para los detalles de rendimiento:

Desafortunadamente, MySQL no permite el uso de la tabla de destino en una subconsulta en una declaración UPDATE, es por eso que deberá apegarse a la sintaxis LEFT JOIN menos eficiente.

+0

Trató eso. Da un error de sintaxis cerca de 'donde ...'. –

+1

Claro. Ver la actualización de la publicación. – Quassnoi

+0

No funciona en Oracle. Ver este [post] (http://stackoverflow.com/questions/2446764/oracle-update-statement-with-inner-join) en ese caso. –

23

Lo mismo se puede aplicar a un escenario donde los datos se han normalizado, pero ahora desea que una tabla tenga valores encontrados en una tercera tabla. Lo siguiente le permitirá actualizar una tabla con información de una tercera tabla que le gusta a una segunda tabla.

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; 

Esto sería útil en un caso en el que tuvo usuarios y grupos, y que quería que un usuario sea capaz de añadir su propia variación del nombre del grupo, por lo que originalmente se querría importar los nombres de los grupos existentes en el campo donde el usuario podrá modificarlo.

4
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 | 

Voy a actualizar el texto de campo en el cuadro A con

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` 

y llegar a este resultado:

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 |      | 
--------+-------------------------+ 

donde se acepta sólo un campo de la Tabla B, pero vendrá a este resultado:

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 |           | 
+--------+--------------------------------------------+ 
0
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`) 
) 
+0

Esto puede no funcionar. –

-1
   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 = ''[email protected]+'' 
            ) 
       and name not in ('Action','Record_ID') 
       FOR XML PATH('') 
      ), 1, 2, '' 
     ) + ']' 


    Select @queryUpd ='Update T1 
SET '[email protected]+' 
FROM '[email protected]+' T1 
INNER JOIN '[email protected]+' T2 
ON T1.Record_ID = T2.Record_Id 
WHERE T2.[Action] = ''Modify''' 
EXEC (@queryUpd) 
+3

¡Agregue una explicación para que la respuesta sea más útil! – namezero

+0

y formatéelo correctamente –