2013-04-04 8 views
6

Ich möchte eine einfache Abfrage schreiben, um eine Anzahl von Spalten in PostgreSQL auszuwählen. Allerdings bekomme ich immer Fehler - ich habe ein paar Optionen ausprobiert, aber sie haben nicht für mich funktioniert. Im Moment bin ich immer folgende Fehlermeldung:Wählen Sie Spalten mit bestimmten Spaltennamen in PostgreSQL

org.postgresql.util.PSQLException: ERROR: syntax error at or near "column"

Um die Spalten mit Werten zu erhalten versuche ich die followig:

select * from weather_data where column like '%2010%' 

Irgendwelche Ideen?

+1

Versuchen Sie, Spalten zurückzugeben, die 2010 in ihnen enthalten, oder versuchen Sie Zeilen zurückzugeben, wo eine bestimmte Spalte den Wert 2010 enthalten hat? Sie können nicht eine Liste von Spalten so wählen (gut, vielleicht mit dynamischem sql konnten Sie) ... – sgeddes

+0

Haben Sie eine Spalte Spalte genannt? –

+0

Nun, ich versuche Spalten mit 2010 als Teil ihres Namens zurückzugeben. Zum Beispiel gibt es Spalten mit dem Namen: m01y2010 - so will ich das, sowie: m02y2010 ... usw. - und Werte, die in ihnen Spalten gespeichert sind. Es gibt also keine Möglichkeit, eine Liste von Spalten mit 2010 in ihrem Namen auszuwählen !? –

Antwort

8

column ein reserved word ist. Sie können es nicht als Bezeichner verwenden, wenn Sie es nicht doppelt angeben. Wie: "column".

Bedeutet aber nicht, dass Sie sollten. Verwenden Sie keine reservierten Wörter als Identifikatoren. Je.

To ...

select a list of columns with 2010 in their name:

.. können Sie diese Funktion verwenden, um den SQL-Befehl dynamisch aus der Systemkatalog Tabelle pg_attribute zu bauen:

CREATE OR REPLACE FUNCTION f_build_select(_tbl regclass, _pattern text) 
    RETURNS text AS 
$func$ 
    SELECT format('SELECT %s FROM %s' 
       , string_agg(quote_ident(attname), ', ') 
       , $1) 
    FROM pg_attribute 
    WHERE attrelid = $1 
    AND attname LIKE ('%' || $2 || '%') 
    AND NOT attisdropped -- no dropped (dead) columns 
    AND attnum > 0;  -- no system columns 
$func$ LANGUAGE sql; 

Call:

SELECT f_build_select('weather_data', '2010'); 

Gibt etwas zurück wie:

SELECT foo2010, bar2010_id, FROM weather_data; 

Sie können dies nicht vollständig dynamisch machen, da der Rückgabetyp unbekannt ist, bis wir die Abfrage tatsächlich erstellen.

+1

Em, tat ich eigentlich nicht - Ich habe nur versucht, nach Spaltennamen mit 2010 zu suchen als Teil ihres Namens, nicht die Spalte namens Spalte mit 2010 als Teil eines der Werte ... –

+0

Danke! Benutzte deine Lösung! –

0

Sie können nicht alle Spalten so suchen. Sie müssen eine bestimmte Spalte angeben.

Zum Beispiel

select * from weather_data where weather_date like '%2010%' 

oder noch besser, wenn es ein Datum ist, geben Sie einen Datumsbereich:

select * from weather_data where weather_date between '2010-01-01' and '2010-12-31' 
5

Dies wird Ihnen die Liste der Spalten in einer bestimmten Tabelle erhalten (Sie Schema optional hinzufügen können, wenn erforderlich):

SELECT column_name 
FROM information_schema.columns 
WHERE table_name = 'yourtable' 
    and column_name like '%2010%' 

SQL Fiddle Demo

Sie können dann diese Abfrage verwenden, um eine dynamische SQL-Anweisung zu erstellen um deine Ergebnisse zurückzugeben.

1

Versuche, dynamische Strukturen wie diese zu verwenden, weisen normalerweise darauf hin, dass Sie Datenformate wie hstore, json, xml usw. verwenden sollten, die für dynamischen Zugriff zugänglich sind.

Sie können erhalten Sie eine dynamische Spaltenliste durch Erstellen der SQL im laufenden Betrieb in Ihrer Anwendung. Sie können die INFORMATION_SCHEMA abfragen, um Informationen zu den Spalten einer Tabelle abzurufen und die Abfrage zu erstellen.

Es ist möglich, dies in PL/PgSQL zu tun, und die erzeugte Abfrage mit EXECUTE laufen, aber Sie finden es etwas schwierig RECORD mit dem Ergebnis, zu arbeiten, wie Sie Composite-Tupel erhalten und entschlüsseln müssen Sie das nicht erweitern Ergebnis wird in eine normale Spaltenliste gesetzt. Beobachten:

craig=> CREATE OR REPLACE FUNCTION retrecset() returns setof record as $$ 
values (1,2,3,4), (10,11,12,13); 
$$ language sql; 

craig=> select retrecset(); 
    retrecset 
--------------- 
(1,2,3,4) 
(10,11,12,13) 
(2 rows) 

craig=> select * from retrecset(); 
ERROR: a column definition list is required for functions returning "record" 

craig=> select (r).* FROM (select retrecset()) AS x(r); 
ERROR: record type has not been registered 

Über alles, was Sie tun können, ist die rohe Aufzeichnung und entschlüsseln Sie es im Client. Sie können es nicht von SQL aus indizieren, Sie können es nicht in etwas anderes konvertieren usw. Die meisten Client-APIs bieten keine Möglichkeiten zum Parsen der Textdarstellungen anonymer Datensätze, so dass Sie diese wahrscheinlich selbst schreiben müssen.

Also: Sie können dynamische Datensätze von PL/PgSQL zurückgeben, ohne zu wissen, ihre Ergebnisart, es ist nur nicht besonders nützlich, und es ist ein Schmerz, auf der Clientseite zu behandeln. Sie möchten wirklich nur den Client verwenden, um Abfragen in erster Linie zu generieren.

+0

Und mit "etwas schwierig" meinst du "fast unmöglich", da der Rückgabetyp unbekannt ist. Sie müssten eine Spaltendefinitionsliste bereitstellen. Wenn Sie jedoch die Spaltendefinitionsliste kennen, benötigen Sie die dynamische Abfrage nicht. Catch 22. –

+0

@ErwinBrandstetter Sie können eine Funktion aufrufen, die "record" oder "setof record" ohne eine Spaltendefinitionsliste zurückgibt, wenn Sie mit einem nicht erweiterten anonymen Datensatz in der Ergebnismenge zufrieden sind. Siehe aktualisierte Antwort. –

+0

+1 Nettes Update. Klärt das Problem auf. –

0

diese here Gefunden:

SELECT 'SELECT ' || array_to_string(ARRAY(SELECT 'o' || '.' || c.column_name 
     FROM information_schema.columns As c 
      WHERE table_name = 'officepark' 
      AND c.column_name NOT IN('officeparkid', 'contractor') 
    ), ',') || ' FROM officepark As o' As sqlstmt 

Das Ergebnis ist eine SQL-SELECT-Abfrage ist einfach weiter ausführen müssen. Es passt meine Bedürfnisse seit Rohr ich das Ergebnis in der Schale wie folgt aus:

psql -U myUser -d myDB -t -c "SELECT...As sqlstm" | psql -U myUser -d myDB 

Das hat mich die formatierte Ausgabe zurückgibt, aber es funktioniert nur in der Schale. Hoffe das hilft jemandem irgendwann.

Verwandte Themen