Gibt es einen Weg zu SELECT
allen Spalten in einer Tabelle, außer zu bestimmten? Es wäre sehr praktisch, alle nicht-blob- oder nicht-geometrischen Spalten aus einer Tabelle auszuwählen.
So etwas wie:
SELECT * -the_geom FROM segments;
- Ich habe einmal gehört, dass diese Funktionalität absichtlich vom SQL-Standard ausgeschlossen wurde, da das Hinzufügen von Spalten zur Tabelle die Abfrageergebnisse verändert. Ist das wahr? Ist das Argument gültig?
- Gibt es eine Problemumgehung, insbesondere in PostgreSQL?
postgresql
sql-standard
Adam Matan
quelle
quelle
name
,age
,sid
), die sich gut in die Bildschirmbreite, alongwith eine lange binäre passtgeom
Spalte. Ich möchte alle Felder mit Ausnahme der Geometrie-Binärdatei abfragen, und es ist mühsam, ihre Namen nacheinander zu schreiben.select (!coluns2,!column5) from sometable;
Antworten:
Eine solche Funktion gibt es weder in Postgres noch im SQL-Standard (AFAIK). Ich halte das für eine sehr interessante Frage, deshalb habe ich ein wenig gegoogelt und bin auf einen interessanten Artikel auf postgresonline.com gestoßen .
Sie zeigen einen Ansatz, der die Spalten direkt aus dem Schema auswählt:
Sie könnten eine Funktion erstellen, die so etwas tut. Solche Themen wurden auch auf den Mailinglisten diskutiert, aber der allgemeine Konsens war ziemlich gleich: Fragen Sie das Schema ab.
Ich bin mir sicher, dass es andere Lösungen gibt, aber ich denke, dass sie alle eine Art magisches Schema-Abfragen-Foo beinhalten werden.
Übrigens: Seien Sie vorsichtig,
SELECT * ...
da dies Leistungseinbußen nach sich ziehen kannquelle
Die wirkliche Antwort ist, dass man das praktisch einfach nicht kann. Dies ist seit Jahrzehnten ein begehrtes Feature und wird von den Entwicklern nicht mehr implementiert.
Die verbreitete Antwort, die vorschlägt, die Schematabellen abzufragen, kann nicht effizient ausgeführt werden, da der Postgres-Optimierer dynamische Funktionen als Black Box ansieht (siehe Testfall unten). Dies bedeutet, dass Indizes nicht verwendet und Verknüpfungen nicht intelligent ausgeführt werden. Mit einem Makrosystem wie m4 wäre es viel besser für Sie. Zumindest wird es den Optimierer nicht verwirren (aber es kann Sie trotzdem verwirren.) Ohne den Code zu forken und das Feature selbst zu schreiben oder eine Programmiersprachenschnittstelle zu verwenden, stecken Sie fest.
Ich habe unten einen einfachen Proof of Concept geschrieben, der zeigt, wie schlecht die Leistung bei einer sehr einfachen dynamischen Ausführung in plpgsql wäre. Beachten Sie auch, dass ich unten eine Funktion erzwingen muss, die einen generischen Datensatz in einen bestimmten Zeilentyp zurückgibt, und die Spalten aufzählen muss. Diese Methode funktioniert also nicht für "Alles auswählen, aber", es sei denn, Sie möchten diese Funktion für alle Ihre Tabellen neu erstellen.
Wie Sie sehen können, hat der Funktionsaufruf die gesamte Tabelle durchsucht, während die direkte Abfrage den Index verwendete ( 95,46 ms gegenüber 00,07 ms ). Diese Art von Funktionen würden jede Art von komplizierter Abfrage speichern , die zur Verwendung von Indizes oder zum Verknüpfen von Tabellen in der richtigen Reihenfolge erforderlich ist .
quelle
Es ist tatsächlich mit PostgreSQL ab 9.4 möglich, wo JSONB eingeführt wurde. Ich habe über ähnliche Fragen nachgedacht, wie alle verfügbaren Attribute in Google Map (über GeoJSON) angezeigt werden sollen.
johto on irc channel schlug vor, ein Element aus JSONB zu löschen.
Hier ist die Idee
Während Sie json anstelle von einzelnen Spalten erhalten, war es genau das, was ich wollte. Vielleicht kann json wieder in einzelne Spalten erweitert werden.
quelle
Die einzige Möglichkeit, dies zu tun, ist die Verwendung dynamischer SQL-Anweisungen. Es ist einfach (wie DrColossos geschrieben hat), die Systemansichten abzufragen, die Struktur der Tabelle zu ermitteln und die richtigen Anweisungen zu erstellen.
PS: Warum sollten Sie alle / einige Spalten auswählen, ohne Ihre Tabellenstruktur genau zu kennen / zu schreiben?
quelle
Dynamisch wie oben angegeben ist die einzige Antwort, aber ich werde es nicht empfehlen. Was ist, wenn Sie auf lange Sicht weitere Spalten hinzufügen, diese aber für diese Abfrage nicht unbedingt erforderlich sind?
Sie würden anfangen, mehr Spalte zu ziehen, als Sie benötigen.
Was ist, wenn der Select Teil eines Inserts wie in ist?
Einfügen in TabelleA (Spalte1, Spalte2, Spalte3 .. Spalte) Wählen Sie mit Ausnahme von 2 Spalten AUS TabelleB alles aus
Die Spaltenübereinstimmung ist falsch und Ihre Einfügung schlägt fehl.
Es ist möglich, aber ich empfehle trotzdem, jede benötigte Spalte für jede geschriebene Auswahl zu schreiben, auch wenn fast jede Spalte erforderlich ist.
quelle
SELECT
s.Wenn Ihr Ziel darin besteht, während des Debuggens Unordnung vom Bildschirm zu entfernen, indem keine Spalten mit großen Datenwerten angezeigt werden, können Sie den folgenden Trick anwenden:
(Installieren Sie das Contrib-Paket "hstore", falls Sie es noch nicht haben: "
CREATE EXTENSION hstore;
")Für eine Tabelle "test" mit col1, col2, col3 können Sie den Wert von "col2" auf null setzen, bevor Sie Folgendes anzeigen:
Oder setzen Sie zwei Spalten auf null, bevor Sie anzeigen:
Die Einschränkung ist, dass "test" eine Tabelle sein muss (ein Alias oder eine Unterauswahl funktioniert nicht), da der Datensatztyp definiert werden muss, der in hstore eingespeist wird.
quelle
Es gibt eine Problemumgehung, die ich gerade entdeckt habe, die jedoch das Senden von SQL-Abfragen aus R erfordert. Sie kann für R-Benutzer hilfreich sein.
Grundsätzlich
dplyr
sendet das Paket SQL- (und insbesondere PostgreSQL-) Anfragen und akzeptiert das-(column_name)
Argument.So könnte Ihr Beispiel wie folgt geschrieben werden:
quelle
In einem Kommentar erklären Sie, dass Ihr Motiv darin besteht, den Inhalt von Spalten mit langem Inhalt nicht anzuzeigen, anstatt die Spalte selbst nicht anzuzeigen:
Dies ist mit Hilfe einer Hilfsfunktion möglich, die den langen Inhalt durch ersetzt
null
(jedetext
Spalte in meinem Beispiel, aber Sie würden dies für die Typen ändern, die Sie unterdrücken möchten):dbfiddle hier
quelle
Aus Sicht der Anwendung ist dies eine träge Lösung. Es ist unwahrscheinlich, dass eine Anwendung automatisch weiß, was mit den neuen Spalten zu tun ist.
Datenbrowseranwendungen fragen möglicherweise die Metadaten nach den Daten ab und schließen die Spalten von den ausgeführten Abfragen aus oder wählen eine Teilmenge der Spaltendaten aus. Neue BLOBs können beim Hinzufügen ausgeschlossen werden. BLOB-Daten für bestimmte Zeilen können bei Bedarf ausgewählt werden.
In jeder SQL-Variante, die dynamische Abfragen unterstützt, kann die Abfrage mithilfe einer Abfrage der Tabellen-Metadaten erstellt werden. Für Ihre Absicht würde ich Spalten basierend auf dem Typ und nicht auf dem Namen ausschließen.
quelle
Sie sehen nie
*
in SQL-VIEWS ... überprüfen Sie\d any_view
an Ihrempsql
. Es gibt eine (introspektive) Vorverarbeitung für die interne Repräsentation.Alle hier zur Diskussion zeigt , dass die Frage Vorschlag (implizit in der Frage und Diskussionen) eine Syntax Zucker für Programmierer ist, nicht ein echtes „SQL - Optimierung Problem“ ... Nun, meine Vermutung, es für 80% des Programmierers ist.
Kann also als " Pre-Parsing mit Introspection" implementiert werden ... Sehen Sie, was PostgreSQL macht, wenn Sie eine SQL-VIEW deklarieren mit
SELECT *
: Der VIEW-Konstruktor wandelt sich*
in eine Liste aller Spalten um (nach Introspection und zum Zeitpunkt der Ausführung der CREATE VIEW-Quellcode).Implementierung für CREATE VIEW und PREPARE
Es ist eine praktikable Implementierung. Angenommen, eine Tabelle
t
mit Feldern(id serial, name text, the_geom geom)
.Gleiches gilt für die PREPARE-Anweisung .
... also, das ist möglich und das ist es, was 80% der Programmierer brauchen, ein Syntaxzucker für PREPARE und VIEWS!
HINWEIS: natürlich die tragfähige Syntax vielleicht nicht der Fall ist
- column_name
, wenn es einige Konflikte in PostgreSQL sind, so können wir vorschlagenEXCEPT column_name
,EXCEPT (column_name1, column_name2, ..., column_nameN)
oder andere.quelle
Dies ist meine Funktion, um alle Spalten auszuwählen, die eine erwarten. Ich habe Ideen von postgresonline.com und postgresql tuturial und aus anderen Quellen kombiniert .
quelle