ACTUALIZAR varias tablas en MySQL usando LEFT JOIN
Tengo dos tablas, y quiero actualizar los campos en T1 para todas las filas en una UNIÓN IZQUIERDA.
Para un ejemplo sencillo, actualice todas las filas del siguiente conjunto de resultados:
SELECT T1.* FROM T1 LEFT JOIN T2 ON T1.id = T2.id WHERE T2.id IS NULL
El Manual de MySQL establece que:
Las instrucciones de ACTUALIZACIÓN de tabla múltiple pueden usar cualquier tipo de combinación permitida en las instrucciones SELECT, como la COMBINACIÓN IZQUIERDA.
Pero no puedo encontrar la sintaxis adecuada para hacer eso en la ACTUALIZACIÓN documentada de tablas múltiples.
¿Qué es el sintaxis correcta?
5 answers
UPDATE t1
LEFT JOIN
t2
ON t2.id = t1.id
SET t1.col1 = newvalue
WHERE t2.id IS NULL
Tenga en cuenta que para un SELECT
sería más eficiente utilizar 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 detalles de rendimiento:
-
Encontrar pedidos incompletos: rendimiento de
LEFT JOIN
en comparación conNOT IN
Desafortunadamente, MySQL
no permite usar la tabla de destino en una subconsulta en una instrucción UPDATE
, por eso necesitará atenerse a una sintaxis LEFT JOIN
menos eficiente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-30 13:46:13
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 tenía usuarios y grupos, y quería que un usuario pudiera agregar su propia variación del nombre del grupo, por lo que originalmente querría importar los nombres de grupo existentes en el campo donde el usuario va a poder modificarlo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-07 19:31:00
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 |
Actualizaré el texto del campo en la tabla 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 solo se acepta un campo de la Tabla B, pero llegaré 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 | |
+--------+--------------------------------------------+
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-14 16:55:36
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`)
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-20 14:58:05
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-06 12:01:46