2013-04-04 19 views
6

Chcę napisać proste zapytanie, aby wybrać liczbę kolumn w PostgreSQL. Jednak ciągle dostaję błędy - próbowałem kilku opcji, ale nie działały one dla mnie. W tej chwili otrzymuję następujący błąd:Wybieranie kolumn z określonymi nazwami kolumn w PostgreSQL

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

aby uzyskać kolumny z wartościami próbuję followig:

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

jakieś pomysły?

+1

Czy próbujesz zwrócić kolumny, które zawierają w nich rok 2010, czy próbujesz zwrócić wiersze, w których konkretna kolumna ma wartość 2010? Nie możesz wybrać listy kolumn takich jak ta (cóż, być może z dynamicznym sql, jaki mógłbyś) ... – sgeddes

+0

Czy masz kolumnę o nazwie column? –

+0

Cóż, próbuję zwrócić kolumny z 2010 jako część ich nazwy. Na przykład są kolumny o nazwie: m01y2010 - więc chcę tego, a także: m02y2010 ... itd. - i wartości, które są w nich przechowywane kolumny. Tak więc nie ma możliwości wyboru listy kolumn z 2010 w ich nazwie !? –

Odpowiedz

8

column jest reserved word. Nie możesz go użyć jako identyfikatora, chyba że podasz go podwójnie. Podoba się: "column".

To nie znaczy, że powinieneś. Po prostu nie używaj słów zarezerwowanych jako identyfikatorów. Zawsze.

Aby ...

select a list of columns with 2010 in their name:

.. można użyć tej funkcji, aby zbudować polecenia SQL dynamicznie od pg_attribute układ tabeli katalogowy:

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'); 

Zwraca coś takiego:

SELECT foo2010, bar2010_id, FROM weather_data; 

Nie można uczynić tego w pełni dynamicznym, ponieważ typem powrotu jest nieznany, dopóki właściwie nie zbudujemy zapytania.

+1

Em, właściwie nie - szukałem tylko nazw kolumn z 2010 jako część nazwy, a nie kolumny o nazwie kolumna z 2010 r. jako część jednej z wartości ... –

+0

Dzięki! Wykorzystałeś swoje rozwiązanie! –

0

Nie można przeszukiwać wszystkich takich kolumn. Musisz podać konkretną kolumnę.

Na przykład

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

albo jeszcze lepiej, jeśli jest to data, należy określić zakres dat:

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

To będzie Ci listę kolumn w określonej tabeli (można opcjonalnie dodać schemat w razie potrzeby):

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

SQL Fiddle Demo

Następnie można użyć tej kwerendy do tworzenia dynamicznych instrukcji SQL aby zwrócić twoje wyniki.

1

Próby użycia struktur dynamicznych jak to zwykle oznacza, że ​​należy używać formatów danych, jak hstorejson, xml, etc, które są amenible z dynamicznym dostępem.

Możesz można uzyskać uzyskać dynamiczną listę kolumn, tworząc SQL w locie w aplikacji. Możesz wysłać zapytanie do INFORMATION_SCHEMA, aby uzyskać informacje o kolumnach tabeli i utworzyć zapytanie.

Jest możliwe, aby to zrobić w PL/PGSQL i uruchomić wygenerowanego zapytania z EXECUTE ale znajdziesz to nieco trudne do pracy w związku z RECORD, jak należy uzyskać i zdekodować kompozytowe krotki, nie można rozwinąć wynik ustawiony na normalną listę kolumn. Obserwuj:

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 

Wszystko, co możesz zrobić, to uzyskać surowy rekord i odszyfrować go w kliencie. Nie można go indeksować za pomocą SQL, nie można go przekonwertować na nic innego itd. Większość interfejsów API klienta nie zapewnia funkcji do analizowania reprezentacji tekstowych anonimowych rekordów, więc prawdopodobnie będziesz musiał napisać to sam.

Tak więc: ty możesz zwrócić rekordy dynamiczne z PL/PgSQL bez znajomości ich typu wyniku, to nie jest po prostu użyteczne i jest to trudny do opanowania po stronie klienta. Naprawdę chcesz po prostu użyć klienta do generowania zapytań w pierwszej kolejności.

+0

A przez "nieco trudne", masz na myśli "prawie niemożliwe", ponieważ typ zwrotu jest nieznany. Będziesz musiał podać listę definicji kolumn, ale jeśli znasz listę definicji kolumn, nie będziesz potrzebował od razu zapytania dynamicznego. Catch 22. –

+0

@ErwinBrandstetter Możesz wywołać funkcję, która zwraca 'record' lub' setof record' bez listy definicji kolumn, jeśli jesteś zadowolony z nieoczekiwanego anonimowego rekordu w zestawie wyników. Zobacz zaktualizowaną odpowiedź. –

+0

+1 Niezła aktualizacja. Wyjaśnia problem. –

0

Znaleziony ten here:

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 

Rezultatem jest zapytanie SQL SELECT po prostu trzeba wykonać dalej. To pasuje do moich potrzeb, odkąd rurze wynik w powłoce tak:

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

która zwraca mi sformatowany wyjście, ale to działa tylko w powłoce. Mam nadzieję, że to pomoże komuś kiedyś.

Powiązane problemy