以下是动态旋转的功能:
create extension tablefunc;
-- tablename: name of source table you want to pivot
-- rowc: the name of the column in source table you want to be the rows
-- colc: the name of the column in source table you want to be the columns
-- cellc: an aggregate expression determining how the cell values will be created
-- celldatatype: desired data type for the cells
----------
create or replace function pivotcode(tablename varchar, rowc varchar, rowd varchar,colc varchar, cellc varchar, celldatatype varchar) returns varchar language plpgsql as $$
declare
dynsql1 varchar;
dynsql2 varchar;
columnlist varchar;
begin
-- 1. retrieve list of column names.
dynsql1 = 'select string_agg(distinct ''_''||'||colc||'||'' '||celldatatype||''','','' order by ''_''||'||colc||'||'' '||celldatatype||''') from '||tablename||';';
execute dynsql1 into columnlist;
-- 2. set up the crosstab query
dynsql2 = 'select * from crosstab (''select '||rowc||','||rowd||','||colc||','||cellc||' from '||tablename||' group by 1,2,3 order by 1,2,3'',''select distinct '||colc||' from '||tablename||' order by 1'')as newtable ('||rowc||' varchar,'||rowd||' varchar,'||columnlist||' );';
return dynsql2;end$$
-- toy example to show how it works
create table table_to_pivot (dates varchar,article varchar,promo varchar);
insert into table_to_pivot values ('11-02-2013','abc',11);
insert into table_to_pivot values ('11-02-2013','def',12);
insert into table_to_pivot values ('12-02-2013','abc',11);
insert into table_to_pivot values ('12-02-2013','def',11);
insert into table_to_pivot values ('13-02-2013','ghi',22);
insert into table_to_pivot values ('14-02-2013','def',12);
insert into table_to_pivot values ('15-02-2013','abc',22);
insert into table_to_pivot values ('16-02-2013','ghi',32);
insert into table_to_pivot values ('17-02-2013','acb',12);
dates |promo |article|
2013-02-11 abc 11
2013-02-11 def 12
2013-02-12 abc 11
2013-02-12 def 11
2013-02-13 ghi 22
2013-02-14 def 12
2013-02-15 abc 22
2013-02-16 ghi 32
2013-02-17 acb 12
select pivotcode('table_to_pivot','dates','article','promo','max(1)','integer');
select * from crosstab (
'select dates,article,promo,max(1) from table_to_pivot group by 1,2,3 order by 1,2,3',
'select distinct promo from table_to_pivot order by 1'
)
as newtable (
dates date,article varchar,_abc integer,_def integer,_ghi integer,_acb integer
);
输出表为:
dates |article |abc | def| ghi | acd
2013-02-11 11 1 null 1 null
2013-02-12 11 1 null 1 null
2013-02-13 22 null null null 1
2013-02-14 12 null null null 1
2013-02-15 22 1 null null null
2013-02-16 32 null null null 1
2013-02-17 12 null 1 null null
有2个错误:
- 列名及其值不准确(例如,“abc”的值在“ghi”列中)
weareas 在不同的文章的相同日期进行不同的促销,我得到的输出只是第一个日期及其文章
结果表应该是
dates |article |abc | def | ghi | acd 2013-02-11 11 1 null null null 2013-02-11 12 null 1 null null 2013-02-12 11 1 null null null 2013-02-12 11 null 1 null null 2013-02-13 22 null null 1 null 2013-02-14 12 null 1 null null 2013-02-15 22 1 null null null 2013-02-16 32 null null 1 null 2013-02-17 12 null null null 1