CREATE TABLE AS vs SELECT INTO

16

PostgreSQL unterstützt CREATE TABLE ASund SELECT INTOwann verwende ich beide?

CREATE TABLE AS - Definieren Sie eine neue Tabelle aus den Ergebnissen einer Abfrage

CREATE TABLE ASErstellt eine Tabelle und füllt sie mit Daten, die mit einem SELECTBefehl berechnet wurden . Die Tabellenspalten haben die Namen und Datentypen, die den Ausgabespalten von zugeordnet sind SELECT(außer dass Sie die Spaltennamen überschreiben können, indem Sie eine explizite Liste neuer Spaltennamen angeben).

CREATE TABLE ASähnelt der Erstellung einer Ansicht, ist aber ganz anders: Sie erstellt eine neue Tabelle und wertet die Abfrage nur einmal aus, um die neue Tabelle anfangs zu füllen. In der neuen Tabelle werden nachfolgende Änderungen an den Quellentabellen der Abfrage nicht nachverfolgt. Im Gegensatz dazu wertet eine Ansicht ihre definierende SELECTAnweisung immer dann neu aus, wenn sie abgefragt wird.

Und dann.

SELECT INTO - Definieren Sie eine neue Tabelle aus den Ergebnissen einer Abfrage

SELECT INTOErstellt eine neue Tabelle und füllt sie mit Daten, die von einer Abfrage berechnet wurden. Die Daten werden nicht wie bei einem normalen Client zurückgegeben SELECT. Die Spalten der neuen Tabelle haben die Namen und Datentypen, die den Ausgabespalten der Tabelle zugeordnet sind SELECT.

Evan Carroll
quelle

Antworten:

15

Ohne die Erklärung immer CREATE TABLE ASohne Ausnahme verwenden. Am Ende jeder unter NOTES ist dies geklärt,

Notizen für SELECT INTO,

CREATE TABLE ASist funktional ähnlich zu SELECT INTO. CREATE TABLE ASist die empfohlene Syntax, da diese Form von SELECT INTOin ECPG oder PL / pgSQL nicht verfügbar ist, da sie die INTO-Klausel unterschiedlich interpretieren. Darüber hinaus CREATE TABLE ASbietet eine Obermenge der Funktionalität von SELECT INTO.

Notizen für CREATE TABLE AS,

Dieser Befehl ist funktional ähnlich, SELECT INTOwird jedoch bevorzugt, da es weniger wahrscheinlich ist, dass er mit anderen Verwendungen der SELECT INTOSyntax verwechselt wird . Darüber hinaus CREATE TABLE ASbietet eine Obermenge der Funktionalität von SELECT INTO.

Auch im Kompatibilitätsbereich der Dokumentation SELECT INTOgeht es noch weiter,

Der SQL-Standard SELECT INTOrepräsentiert die Auswahl von Werten in skalaren Variablen eines Host-Programms, anstatt eine neue Tabelle zu erstellen. Dies ist in der Tat die Verwendung in ECPG (siehe Kapitel 34) und PL / pgSQL (siehe Kapitel 41). Die Verwendung von PostgreSQL SELECT INTOzur Darstellung der Tabellenerstellung ist historisch. Es ist am besten, CREATE TABLE ASfür diesen Zweck in neuem Code zu verwenden.

Also haben wir,

  1. PostgreSQL hält dies für verwirrend, da SELECT INTOandere Dinge in Kontexten nur in PL / pgSQL und ECPG verfügbar sind.
  2. CREATE TABLEunterstützt mehr Funktionen (ich nehme an, sie beziehen sich auf WITH OIDS, und TABLESPACE, IF NOT EXISTS).
  3. SELECT INTO für die Tabellenerstellung ist "veraltet".

Als Randnotiz kann die Syntax für ein CTAS mit einem CTE ein bisschen komisch aussehen. , und SELECT INTO kann auch eine Art Einfluss auf QUELs seinRETRIEVE INTO . QUEL war der Vorgänger von SQL, der Vorgänger von PostgreSQL (INGRES).

Evan Carroll
quelle
1

Mir ist noch etwas aufgefallen, das in der akzeptierten Antwort fehlt. Using CREATE TABLE ASbehält das nullable-Attribut jeder Spalte bei, das von ignoriert zu werden scheint SELECT INTO.

Allein auf dieser Basis würde ich empfehlen CREATE TABLE AS. Ein häufiger Anwendungsfall für beide Anweisungen ist das Laden von Daten aus einer Abfrage mit langer Laufzeit in eine Tabelle, ohne diese Tabelle für die Dauer Ihrer Abfrage zu sperren. Sie erstellen eine temporäre Tabelle mit einem der oben genannten Befehle, fügen dort die Ergebnisse der Langzeitabfrage ein und fügen diese Ergebnisse dann in die Originaltabelle ein. Das Beibehalten des Attributs nullable in Ihrer temporären Tabelle verringert die Wahrscheinlichkeit, dass Ihre zweite Einfügung fehlschlägt.

Getestet auf PG 11, also vielleicht eine neuere Funktion, da diese Frage beantwortet wurde.

schrumpfen
quelle
Eine lange laufende Abfrage sperrt keine Tabelle. Die Motivation, CTAS aus diesem Grund zu verwenden, ist sinnlos
a_horse_with_no_name