UPDATE mehrere Tabellen in MySQL mit LINKER JOIN

Ich habe zwei Tabellen und möchte Felder in T1 für alle Zeilen in einem LINKEN JOIN aktualisieren.

Um ein einfaches Beispiel zu erhalten, aktualisieren Sie alle Zeilen der folgenden Ergebnismenge:

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

Im MySQL-Handbuch heißt es:

UPDATE-statementen für mehrere Tabellen können alle Arten von Joins verwenden, die in SELECT-statementen zulässig sind, z. B. LEFT JOIN.

Aber ich kann die richtige Syntax dafür in dem dokumentierten Multiple-Tabellen-UPDATE nicht finden.

Was ist die richtige Syntax?

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

    Beachten Sie, dass es für ein SELECT effizienter wäre, die Syntax NOT IN / NOT EXISTS :

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

    Sehen Sie den Artikel in meinem Blog für performancesdetails:

    • Unvollständige Bestellungen finden : performance von LEFT JOIN Vergleich zu NOT IN

    Leider erlaubt es MySQL nicht, die Zieltabelle in einer Unterabfrage in einer UPDATE statement zu verwenden, deshalb müssen Sie sich an die weniger effiziente LEFT JOIN Syntax halten.

    Dasselbe gilt für ein Szenario, in dem die Daten normalisiert wurden. Jetzt möchten Sie jedoch, dass eine Tabelle Werte in einer dritten Tabelle enthält. Im Folgenden können Sie eine Tabelle mit Informationen aus einer dritten Tabelle aktualisieren, die von einer zweiten Tabelle gemocht wird.

     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; 

    Dies wäre nützlich, wenn Sie Benutzer und Gruppen hatten und Sie möchten, dass ein Benutzer eine eigene Variante des Gruppennamens hinzufügen kann. Daher möchten Sie die vorhandenen Gruppennamen ursprünglich in das Feld importieren, in dem sich der Benutzer befindet werde in der Lage sein, es zu ändern.

     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 | 

    Ich werde Feldtext in Tabelle A mit aktualisieren

     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` 

    und komm zu diesem Ergebnis:

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

    wo nur ein Feld aus Tabelle B akzeptiert wird, aber ich werde zu diesem Ergebnis kommen:

     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)