2010-03-03 103 views
7

我對postgresql相當陌生。SELECT語句中的動態列postgres

實現此目標的最佳方法是什麼?

SELECT get_columns() 
    FROM table_name; 

get_columns()將提供查詢的列名稱。我看到有人建議使用EXECUTE語句,但我無法完成這項工作。

比方說有一個與列A,B,C 表測試,我想運行

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

與列名動態生成。

+0

有什麼意義?如果您不知道列名,只需在查詢中使用*即可。也許我錯過了什麼? – 2010-03-03 20:39:49

+0

他在說'get_columns()'會返回*列'a'和'c'或列'a'和'b'。他不希望所有專欄,只是程序生成的專欄。 – cmptrgeekken 2010-03-03 20:41:08

+0

想法是get_columns()將採取一些參數,並因此 將返回適當的列用於某處。 這篇文章對於處理COPY FROM命令時很有用,我需要根據我選擇的csv文件提供列名。 – Sujit 2010-03-03 20:43:32

回答

-2

這是你如何得到一個表中的COLUMNNAMES:

SELECT 
    column_name 
FROM 
    information_schema.columns 
WHERE 
    table_name = 'test'; 
+1

是的,我知道這一點。問題是我們可以動態構造一個SELECT語句嗎? – Sujit 2010-03-03 21:24:50

0

由於您正在使用COPY FROM到已知大表,所以CREATE FUNCTION返回SETOF bigtable並選擇特定類型的所有列,對於在該特定情況下不需要的字段使用NULL AS字段名,像:

# \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

這似乎是錯誤的方式,隨意忽略這個答案 – MkV 2010-03-04 15:07:05

0

您將無法使用函數來生成列列表。我真的不認爲這是解決這個問題的最好方法......這就是說,你可以用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

你的意思是'EXECUTE'SELECT''不是'SELECT'SELECT''吧? – 2012-09-05 09:49:33

+0

@ChrisTravers:該行只是將腳本連接到'p_sql'中。它進一步下降。 – 2012-09-05 12:49:18

+0

啊,我明白了。任何理由不僅僅是做RETURN QUERY EXECUTE'SELECT ...'? – 2012-09-05 12:53:02

0

我覺得你最大的問題是,你需要返回行PostgreSQL可以理解的一種方式。這意味着基本上,您可以返回一個refcursor,或者您可以返回一組一致的數據類型。我更喜歡後者,因爲它從編程的角度使系統更加一致,並且可以採取一些先進的方向,但我也可以看到另一種方式。