2013-12-16 22 views
2

我是PostgreSQL的新手。如何在PostgreSQL中使用動態字段來旋轉/交叉表

id | customer_id | form_id | field_id | field_name | form_submission_id | value  | 
---+-------------+---------+----------+------------+--------------------+--------------+ 
1 |   2 |  7 | c313  | Program |     1 | 2013   |    
2 |   2 |  7 | c313  | Program |     2 | PIP   |    
3 |   2 |  7 | c313  | Program |     3 | CIP   |    
4 |   2 |  7 | c343  | Broker  |     1 | broker test | 
5 |   2 |  7 | c343  | Broker  |     2 | broker test1 |    
6 |   2 |  7 | c343  | Broker  |     3 | broker test2 |    
7 |   2 |  7 | c339  | Class  |     1 | Class test |    
8 |   2 |  7 | c339  | Class  |     2 | Class test1 |    
9 |   2 |  7 | c339  | Class  |     3 | Class test2 |  

我想作爲

customer_id form_id Program  Broker  Class  form_submission_id 
    2   7  2013  broker test Class test  1 
    2   7  PIP  broker test1 Class test1  1 
    2   7  CIP  broker test2 Class test3  1 

FIELD_NAME值將是動態的,不是固定值這樣的紀錄。

我試試這個,但得到這樣的錯誤「ERROR:迴歸和SQL元組的描述是不兼容的」

select * from crosstab (
    'select Distinct customer_id ,form_id , field_name from form_submissions_reports ' 
    ) 
    as newtable (
    customer_id integer,form_id integer,field_id1 varchar,field_id2 varchar,field_id3 varchar 
    ); 

但重要的是它的字段名稱是動態的。

+0

我有谷歌,但沒有得到answerd –

+1

是的,沒錯。相關的contrib是第一個結果,並且相關的StackOverflow dup是bext:http://stackoverflow.com/questions/3002499/postgresql-crosstab-query –

+0

但它具有固定的狀態值。我沒有field_name的固定值 –

回答

1

要設置一個例子:

create table form_submissions_reports (id integer, customer_id integer, 
form_id integer, field_id text, field_name text, form_submission_id integer, 
"value" text); 


insert into form_submissions_reports 
select 1 ,2 ,7 , 'c313', 'Program',1 , '2013' union all 
select 2 ,2 ,7 , 'c313', 'Program',2 , 'PIP' union all 
select 3 ,2 ,7 , 'c313', 'Program',3 , 'CIP' union all 
select 4 ,2 ,7 , 'c343', 'Broker',1 , 'broker test' union all 
select 5 ,2 ,7 , 'c343', 'Broker',2 , 'broker test1' union all 
select 6 ,2 ,7 , 'c343', 'Broker',3 , 'broker test2' union all 
select 7 ,2 ,7 , 'c339', 'Class',1 , 'Class test' union all 
select 8 ,2 ,7 , 'c339', 'Class',2 , 'Class test1' union all 
select 9 ,2 ,7 , 'c339', 'Class',3 , 'Class test2'; 

這是固定的列數,你嘗試瞭解決方案:

select * 
from crosstab (
'select Distinct form_submission_id , customer_id ,form_id , field_name, value 
from form_submissions_reports order by form_submission_id ', 
'select Distinct field_name from form_submissions_reports' 
)as newtable (
       form_submission_id integer, customer_id integer,form_id integer,field_id 
       varchar,field_id2 varchar,field_id3 varchar 
      ); 

關係數據庫,就我自己的經驗,對各類不建不是固定在列數和類型上。所以你必須作弊。

這隻適用於娛樂。我看不出在這個任何生產價值,完全「動態」,溶液(列數靈活,數據驅動的名稱):)

1創建這兩個功能:

CREATE OR REPLACE FUNCTION foo() 
RETURNS text as 
$BODY$ 
DECLARE 
dynamic_columns text; 
BEGIN 

select array_to_string(array_agg(distinct field_name||' text'), ', ') into dynamic_columns from form_submissions_reports; 

return 'select * from crosstab (
     ''select Distinct form_submission_id , customer_id ,form_id , field_name, value from form_submissions_reports order by form_submission_id '', 
    ''select Distinct field_name from form_submissions_reports'' 
    ) 
    as newtable (
    form_submission_id integer, customer_id integer,form_id integer, '|| dynamic_columns ||' 
    )'; 


END; 
$BODY$ 
LANGUAGE plpgsql; 


CREATE OR REPLACE FUNCTION bar() 
RETURNS void as 
$BODY$ 
DECLARE 
dyn_crosstab text; 
BEGIN 

DROP VIEW IF EXISTS barview; 

select foo() into dyn_crosstab; 

execute 'create view barview as '||dyn_crosstab; 

END; 
$BODY$ 
LANGUAGE plpgsql; 

2)執行吧()函數。這將爲您提供新版本的「barview」視圖。之後,查詢barview。

select bar(); 
select * from barview; 

3)爲了測試它的動態,插入新行與FIELD_NAME不同的值,然後重複2):

INSERT INTO form_submissions_reports 
(
    id, customer_id, form_id, field_id, 
    field_name, form_submission_id, value 
) 
VALUES( 10, 2, 7, 'd', 'NEWFIELD', 4, 
    'newfield test'); 

select bar(); 
select * from barview;