0

以下是动态旋转的功能:

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
    
4

1 回答 1

0

您可以使用 antext ARRAY[]来获取应该分组的数据。最好使用双引号而不是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
      ) ;
于 2018-09-05T08:01:23.683 回答