Aktualisieren oder Einfügen (mehrere Zeilen und Spalten) aus der Unterabfrage in PostgreSQL

106

Ich versuche so etwas in postgres zu machen:

  • UPDATE table1 SET (col1, col2) = (SELECT col2, col3 FROM othertable WHERE othertable.col1 = 123);

  • INSERT INTO table1 (col1, col2) VALUES (SELECT col1, col2 FROM othertable)

Punkt 1 ist jedoch auch mit Postgres 9.0 nicht möglich, wie in den Dokumenten erwähnt ( http://www.postgresql.org/docs/9.0/static/sql-update.html ).

Auch Punkt 2 scheint nicht zu funktionieren. Ich erhalte die folgende Fehlermeldung: Unterabfrage darf nur eine Spalte zurückgeben.

Hoffe, jemand hat eine Problemumgehung für mich. Andernfalls dauert die Abfrage einige Zeit :(.

Zu Ihrer Information: Ich versuche, verschiedene Spalten aus mehreren Tabellen auszuwählen und in einer temporären Tabelle zu speichern, damit eine andere Anwendung die vorbereiteten Daten problemlos abrufen kann.

dforce
quelle

Antworten:

175

Für das UPDATE

Verwenden:

UPDATE table1 
   SET col1 = othertable.col2,
       col2 = othertable.col3 
  FROM othertable 
 WHERE othertable.col1 = 123;

Für das INSERT

Verwenden:

INSERT INTO table1 (col1, col2) 
SELECT col1, col2 
  FROM othertable

Sie benötigen die VALUESSyntax nicht, wenn Sie SELECT zum Auffüllen der INSERT-Werte verwenden.

OMG Ponys
quelle
1
Ist es möglich, Update & Insert so zu kombinieren, dass bei einem Fehler das andere verwendet wird, ohne einen Fehler auszulösen (unabhängig für jede Zeile). Ich denke, das wäre eine vollständigere Lösung für die Frage (zum Beispiel: stackoverflow.com/a/6527838/781695 )
Benutzer
26

Die Antwort von OMG Ponies funktioniert einwandfrei, aber für den Fall, dass Sie etwas Komplexeres benötigen, finden Sie hier ein Beispiel für eine etwas erweiterte Update-Abfrage:

UPDATE table1 
SET col1 = subquery.col2,
    col2 = subquery.col3 
FROM (
    SELECT t2.foo as col1, t3.bar as col2, t3.foobar as col3 
    FROM table2 t2 INNER JOIN table3 t3 ON t2.id = t3.t2_id
    WHERE t2.created_at > '2016-01-01'
) AS subquery
WHERE table1.id = subquery.col1;
David Namenyi
quelle
1
Du bist der Beste :) :)
Ashwini
1
perfekt. Dies funktioniert am besten, wenn Sie eine Teilmenge basierend auf einer Bedingung auswählen müssen, die die aktualisierte Tabelle selbst betrifft.
mythicalcoder
@ David Namenyi kannst du diese Frage erklären?
Chintan Pathak
15
UPDATE table1 SET (col1, col2) = (col2, col3) FROM othertable WHERE othertable.col1 = 123;
Walter
quelle