Ihr UPDATE
Abfrage sollte wie folgt aussehen:
UPDATE table2 t2
SET val2 = t1.val1
FROM table1 t1
WHERE t2.table2_id = t1.table2_id
AND t2.val2 IS DISTINCT FROM t1.val1; -- optional, see below
So wie Sie es hatten, gab es keine Verbindung zwischen einzelnen Zeilen der beiden Tabellen. Jede Zeile würde aus table1
abgerufen werden für jede Zeile in table2
. Dies machte (auf teure Weise) keinen Sinn und löste auch den Syntaxfehler aus, da ein Unterabfrageausdruck an dieser Stelle nur einen einzigen Wert zurückgeben darf.
Ich habe dies behoben, indem ich die beiden Tabellen auf table2_id
verbunden habe . Ersetzen Sie das mit dem, was die beiden tatsächlich verbindet.
Ich habe das UPDATE
umgeschrieben in table1
einzufügen (mit dem FROM
-Klausel), anstatt korrelierte Unterabfragen auszuführen, da dies normalerweise um eine Größenordnung schneller ist.
Es verhindert auch, dass table2.val2
annulliert, wenn in table1
keine übereinstimmende Zeile gefunden wird . Stattdessen nichts passiert bei dieser Form der Abfrage mit solchen Zeilen.
Sie können Tabellenausdrücke zu FROM
hinzufügen Liste wie in einem einfachen SELECT
(Tabellen, Unterabfragen, Set-zurückgebende Funktionen, ...). Das Handbuch:
from_list
Eine Liste von Tabellenausdrücken, die das Erscheinen von Spalten aus anderen Tabellen im
WHERE
ermöglicht Bedingung und die Aktualisierungsausdrücke. Dies ähnelt der Liste der Tabellen, die imFROM
angegeben werden können Klausel einesSELECT
Erklärung. Beachten Sie, dass die Zieltabelle nicht in derfrom_list
erscheinen darf , es sei denn, Sie beabsichtigen einen Self-Join (in diesem Fall muss es mit einem Alias in derfrom_list
erscheinen ).
Das abschließende WHERE
-Klausel verhindert Updates, die nichts ändern würden - was praktisch immer eine gute Idee ist (fast volle Kosten, aber kein Gewinn, es gelten exotische Ausnahmen). Wenn sowohl der alte als auch der neue Wert garantiert NOT NULL
sind , vereinfachen zu:
AND t2.val2 <> t1.val1
- Wie wähle ich (oder kann ich) DISTINCT für mehrere Spalten aus?