以下是动态转动的功能:
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个错误:
在相同日期的不同宣传片上使用不同的文章我得到的输出仅仅是第一次约会及其文章
结果表应为
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
答案 0 :(得分:0)
您可以使用text ARRAY[]
来获取应该分组的数据。
最好使用double-dolar quotes而不是single quotes
。
尝试使用此查询;
select newtable.datas[1] as dates,newtable.datas[2] as
article,newtable._abc,newtable._def,newtable._ghi,newtable._acb
from crosstab (
$$select Array[dates,promo,article],article,max(1)
from table_to_pivot group by 1,2 order by 1,2$$,
$$select article from table_to_pivot
group by 1
order by (case
when article = 'abc' then 1
when article = 'def' then 2
when article = 'ghi' then 3
else 4
end)$$
)
as newtable (
datas text[],_abc integer,_def integer,_ghi integer,_acb integer
) ;