2013-12-16 2 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 값이 동적이 아닌 고정 값이됩니다 같은 기록을합니다.

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

그러나 중요 그것은 필드 이름이 동적 '반환 및 SQL 튜플 설명이 호환되지 않는 오류가'

내가 좋아하는이 있지만 점점 오류를 시도합니다. 예를 들어 설정하려면

+0

내가 구글이 있지만 answerd –

+1

그래, 제대로하지. 관련된 contrib가 첫 번째 결과이며 관련 StackOverflow dup은 다음과 같습니다. http://stackoverflow.com/questions/3002499/postgresql-crosstab-query –

+0

그러나 status 값은 고정되어 있습니다. field_name의 고정 값이 없습니다. –

답변

1

는 :

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

관계형 데이터베이스, 지금까지의 내 경험이 지남에 따라, 종류의 내장되지 않습니다

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

이것은 당신이 시도 열 고정 된 수와 솔루션입니다 열의 수와 유형이 고정되어 있지 않습니다. 그래서 당신은 속임수를 써야합니다.

이것은 오락을 위해서만 유용합니다.

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;