动态数据透视,postgresql中的交叉表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态数据透视,postgresql中的交叉表相关的知识,希望对你有一定的参考价值。
以下是动态转动的功能:
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'中)
- 在不同的促销上的wheareas同一日期与不同的文章,我得到的输出只是第一次约会及其文章
- 结果表应该是
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
答案
您可以使用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
) ;
以上是关于动态数据透视,postgresql中的交叉表的主要内容,如果未能解决你的问题,请参考以下文章