Effizient duplizieren Sie einige Zeilen in der PostgreSQL-Tabelle

8

Ich habe eine PostgreSQL 9-Datenbank, die automatisch inkrementierende Ganzzahlen als Primärschlüssel verwendet. Ich möchte einige Zeilen in einer Tabelle kopieren (basierend auf einigen Filterkriterien), während ich einen oder zwei Werte ändere, dh alle Spaltenwerte kopieren, mit Ausnahme der ID (die automatisch generiert wird) und möglicherweise einer anderen Spalte.

Ich möchte aber auch die Zuordnung von alten zu neuen IDs bekommen. Gibt es einen besseren Weg, dies zu tun, dann nur nach den Zeilen zu suchen, die zuerst kopiert werden sollen, und dann neue Zeilen nacheinander einzufügen?

Im Wesentlichen möchte ich so etwas tun:

%Vor%

Das scheitert jedoch mit ERROR: missing FROM-clause entry for table "old" und ich kann sehen, warum: Postgres muss zuerst SELECT ausführen und dann einfügen und die RETURNING -Klauseln haben nur Zugriff auf die neu eingefügte Zeile.

    
EMP 19.08.2011, 01:06
quelle

5 Antworten

8

RETURNING kann nur auf die Spalten in der letzten eingefügten Zeile verweisen. Auf diese Weise kann nicht auf die ID "OLD" verwiesen werden, es sei denn, es gibt eine Spalte in der Tabelle, die sowohl die ID als auch die neue ID enthält.

Versuchen Sie, das auszuführen, was funktionieren sollte, und zeigen Sie alle möglichen Werte an, die Sie über RETURNING erhalten können:

%Vor%

Sie erhalten nicht das gewünschte Verhalten, sollten aber besser veranschaulichen, wie RETURNING funktioniert.

    
Matthew Wood 21.08.2011 00:09
quelle
2

Gut! Ich teste diesen Code, aber ich ändere dies ( FROM my_table AS old ) in ( FROM my_table ) und dies ( WHERE old.some_criteria = 'something' ) in ( WHERE some_criteria = 'something' )

Dies ist der letzte Code, den ich benutze

%Vor%

Danke!

    
pjhooker 17.04.2013 14:47
quelle
2

Dies kann mit Hilfe von Datenmodifizierungs-CTEs (Postgres 9.1 + ) erfolgen:

%Vor%

SQL Fiddle Demonstration.

Dies beruht auf dem nicht dokumentierten Implementierungsdetail, dass Zeilen aus einem SELECT in der angegebenen Reihenfolge eingefügt werden (und in der angegebenen Reihenfolge zurückgegeben werden). Es funktioniert in allen aktuellen Versionen von Postgres und wird nicht kaputt gehen. Verwandt:

Fensterfunktionen sind in der RETURNING -Klausel nicht erlaubt, daher gebe ich row_number() in einer anderen Unterabfrage an.

Weitere Erklärung in dieser verwandten späteren Antwort:

Erwin Brandstetter 25.03.2015 18:51
quelle
0

'alt' ist ein reserviertes Wort, das vom Regelüberschreibsystem verwendet wird. [Ich nehme an, dass dieses Abfragefragment nicht Teil einer Regel ist; in diesem Fall hättest du die Frage anders formuliert]

    
wildplasser 22.08.2011 13:03
quelle
0
%Vor%

fügen Sie vor dem Einfügen ein weiteres Update hinzu, um ein anderes Feld zu ändern

%Vor%     
Brian Keith 30.01.2014 21:15
quelle