我是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值将是动态的,而不是固定值。
我试过这个,但是收到错误如'错误:返回和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 :(得分: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)执行bar()函数。这将为您提供新版“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;