PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Aktualisieren Sie eine Spalte einer Tabelle mit einer Spalte einer anderen Tabelle in PostgreSQL

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 im FROM angegeben werden können Klausel eines SELECT Erklärung. Beachten Sie, dass die Zieltabelle nicht in der from_list erscheinen darf , es sei denn, Sie beabsichtigen einen Self-Join (in diesem Fall muss es mit einem Alias ​​in der from_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?