AKTUALISIEREN Sie mehrere Tabellen in MySQL mit LEFT JOIN


165

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

Aktualisieren Sie für ein einfaches Beispiel alle Zeilen der folgenden Ergebnismenge:

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

Das MySQL-Handbuch besagt Folgendes:

UPDATE-Anweisungen mit mehreren Tabellen können jeden in SELECT-Anweisungen zulässigen Join-Typ verwenden, z. B. LEFT JOIN.

Aber ich kann im dokumentierten UPDATE mit mehreren Tabellen nicht die richtige Syntax dafür finden.

Was ist die richtige Syntax?

Antworten:


318
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 a SELECTeffizienter wäre, NOT IN/ NOT EXISTSsyntax zu verwenden:

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

Weitere Informationen zur Leistung finden Sie im Artikel in meinem Blog:

Die MySQLVerwendung der Zieltabelle in einer Unterabfrage in einer UPDATEAnweisung ist leider nicht zulässig. Deshalb müssen Sie sich an eine weniger effiziente LEFT JOINSyntax halten.


In Oracle funktioniert das nicht. Siehe diesen Beitrag in diesem Fall.
Jon Ander

Können wir dem eine Grenze hinzufügen? Als ob ich nur 10000 Zeilen gleichzeitig aktualisieren möchte. Wenn ich nur LIMIT 10000 hinzufüge, erhalte ich die Fehlermeldung "Falsche Verwendung von UPDATE und LIMIT"
Haril Satra

28

Dasselbe kann auf ein Szenario angewendet werden, in dem die Daten normalisiert wurden. Jetzt möchten Sie jedoch, dass in einer Tabelle Werte in einer dritten Tabelle gefunden werden. Im Folgenden können Sie eine Tabelle mit Informationen aus einer dritten Tabelle aktualisieren, die einer zweiten Tabelle gefällt.

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 ist nützlich, wenn Sie Benutzer und Gruppen hatten und ein Benutzer eine eigene Variation des Gruppennamens hinzufügen kann. Daher möchten Sie ursprünglich die vorhandenen Gruppennamen in das Feld importieren, in dem sich der Benutzer befindet in der Lage sein, es zu ändern.


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  |

Ich werde den 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 kommen 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   |                                            |
+--------+--------------------------------------------+

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

-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 = ''+@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)

3
Bitte fügen Sie eine Erklärung hinzu, um die Antwort nützlicher zu machen!
Namezero
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.