Динамический столбец в инструкции SELECT postgres - PullRequest
8 голосов
/ 03 марта 2010

Я новичок в postgresql.

Каков наилучший способ достичь этого?

SELECT get_columns() 
  FROM table_name;

get_columns() предоставит имена столбцов для запроса. Я видел людей, советующих использовать выражение EXECUTE, но я не мог заставить это работать.

Допустим, есть таблица Test с колонками a, b, c и я хочу бежать

SELECT a,b FROM Test;
SELECT a,c FROM Test;

с динамически генерируемыми именами столбцов.

Ответы [ 6 ]

5 голосов
/ 14 сентября 2011

Чтобы написать динамический запрос, вам нужно сделать что-то вроде:

EXECUTE 'SELECT '|| get_columns()|| ' FROM table_name' INTO results

Пожалуйста, прочитайте документацию: http://developer.postgresql.org/pgdocs/postgres/plpgsql-statements.html

1 голос
/ 04 марта 2010

В таком случае я бы использовал функцию PL / pgSQL, используя курсор .

0 голосов
/ 05 сентября 2012

Я думаю, что ваша самая большая проблема в том, что вам нужно возвращать строки так, чтобы PostgreSQL мог их понять. В основном это означает, что вы можете вернуть refcursor или вы можете вернуть согласованный набор типов данных. Я предпочитаю последнее, потому что оно делает систему немного более последовательной с точки зрения программирования, и есть некоторые продвинутые направления, которые вы можете использовать, но я вижу и другой путь.

0 голосов
/ 06 марта 2010

Вы не сможете использовать функцию для генерации списка столбцов. И я действительно не думаю, что это лучший способ подойти к проблеме ... Тем не менее, вы можете сделать это с 8.4 примерно так:

CREATE OR REPLACE FUNCTION dyn(p_name VARCHAR)
RETURNS SETOF RECORD AS
$$
  DECLARE
    p_sql  TEXT;
  BEGIN
   SELECT 'SELECT ' ||
     CASE p_name WHEN 'foo' THEN ' col1, col2, col3, col4 '
      WHEN 'bar' THEN 'col3, col4, col5, col6'
      WHEN 'baz' THEN 'col1, col3, col4, col6' END ||
   ' FROM mytest'
   INTO p_sql;
   RETURN QUERY EXECUTE p_sql;
  END
$$ LANGUAGE 'plpgsql';

Использование будет: SELECT * FROM dyn ('foo') AS (один int, два int, три int, четыре int)

Но, честно говоря, я бы посоветовал просто сделать просмотр для каждого устройства.

0 голосов
/ 04 марта 2010

Поскольку вы используете COPY FROM для известной большой таблицы, CREATE a FUNCTION, которая возвращает SETOF bigtable и SELECT выбирает все столбцы определенного типа, используйте NULL AS fieldname для полей, которые не требуются в этом конкретном случае, что-то вроде :

# \d SMALL
     Table "public.small"
 Column |  Type   | Modifiers 
--------+---------+-----------
 a      | integer | 
 b      | integer | 
 c      | integer | 
 d      | integer | 

# \d LARGE
     Table "public.large"
 Column |  Type   | Modifiers 
--------+---------+-----------
 a      | integer | 
 b      | integer | 
 c      | integer | 
 d      | integer | 

# CREATE OR REPLACE FUNCTION myData()
 RETURNS SETOF large LANGUAGE SQL AS $$
SELECT a, 
       CASE WHEN a = 1 
            THEN b 
       ELSE 
            NULL 
END as b, 
       CASE WHEN a = 2 
            THEN c 
       ELSE 
            NULL
END AS c, 
d
FROM small;
$$;

# SELECT * FROM mydata();
# COPY (SELECT * FROM myData()) TO STDOUT;

Очевидно, что SQL может быть не лучшим языком для использования, поэтому PL / PgSQL или PL / Perl (или любой другой) могут быть подходящими.

0 голосов
/ 03 марта 2010

Вот как вы получаете имена столбцов в таблице:

SELECT 
  column_name 
FROM 
  information_schema.columns 
WHERE 
  table_name = 'test';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...