我對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;
與列名動態生成。
我對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;
與列名動態生成。
這是你如何得到一個表中的COLUMNNAMES:
SELECT
column_name
FROM
information_schema.columns
WHERE
table_name = 'test';
是的,我知道這一點。問題是我們可以動態構造一個SELECT語句嗎? – Sujit 2010-03-03 21:24:50
在這種情況下,我會用PL/pgSQL function using cursor。
由於您正在使用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的(或其他)是合適的。
這似乎是錯誤的方式,隨意忽略這個答案 – MkV 2010-03-04 15:07:05
您將無法使用函數來生成列列表。我真的不認爲這是解決這個問題的最好方法......這就是說,你可以用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)
但是,老實說,我建議只是爲每個設備製作一個視圖。
你的意思是'EXECUTE'SELECT''不是'SELECT'SELECT''吧? – 2012-09-05 09:49:33
@ChrisTravers:該行只是將腳本連接到'p_sql'中。它進一步下降。 – 2012-09-05 12:49:18
啊,我明白了。任何理由不僅僅是做RETURN QUERY EXECUTE'SELECT ...'? – 2012-09-05 12:53:02
爲了寫一個動態查詢,你將不得不做這樣的事情:
EXECUTE 'SELECT '|| get_columns()|| ' FROM table_name' INTO results
請閱讀文檔: http://developer.postgresql.org/pgdocs/postgres/plpgsql-statements.html
我覺得你最大的問題是,你需要返回行PostgreSQL可以理解的一種方式。這意味着基本上,您可以返回一個refcursor,或者您可以返回一組一致的數據類型。我更喜歡後者,因爲它從編程的角度使系統更加一致,並且可以採取一些先進的方向,但我也可以看到另一種方式。
有什麼意義?如果您不知道列名,只需在查詢中使用*即可。也許我錯過了什麼? – 2010-03-03 20:39:49
他在說'get_columns()'會返回*列'a'和'c'或列'a'和'b'。他不希望所有專欄,只是程序生成的專欄。 – cmptrgeekken 2010-03-03 20:41:08
想法是get_columns()將採取一些參數,並因此 將返回適當的列用於某處。 這篇文章對於處理COPY FROM命令時很有用,我需要根據我選擇的csv文件提供列名。 – Sujit 2010-03-03 20:43:32