【问题标题】:Returning empty data from dynamic pivot is there is no data从动态数据透视返回空数据是没有数据
【发布时间】:2016-05-17 22:55:56
【问题描述】:

how to preserve column names on dynamic pivot 下面的代码用于创建动态数据透视表。

如果源表不包含数据,由于创建表列列表以逗号结尾(没有数据透视列),会出现 sql 错误。 如何解决这个问题以便返回空表?

要重现,请删除插入命令

insert into sales values ( '2016-1-1', 'Ø 12.3/3mm', 2);
insert into sales values ( '2016-1-1', '+-3,4%/3mm', 52);
insert into sales values ( '2016-1-3', '/3,2m-', 246);

来自代码。

测试用例:

create temp table sales ( saledate date, productname char(20), quantity int );
insert into sales values ( '2016-1-1', 'Ø 12.3/3mm', 2);
insert into sales values ( '2016-1-1', '+-3,4%/3mm', 52);
insert into sales values ( '2016-1-3', '/3,2m-', 246);

do $do$


declare
voter_list text;
begin

create temp table myyk on commit drop as
select saledate as kuupaev,
  format ('"%s"', replace (upper(productname), ' ', '')) as tootjakood,               
  sum(quantity)::int as kogus 
from sales
group by 1,2
;

drop table if exists pivot;

voter_list := (
    select string_agg(distinct tootjakood, ' ' order by tootjakood) from myyk
    );

execute(format('
    create table pivot (
kuupaev date,
        %1$s
    )', (replace(voter_list, ' ', ' integer, ') || ' integer')
));

execute (format($f$

  insert into pivot
        select
           kuupaev,
            %2$s
        from crosstab($ct$
            select
                kuupaev,tootjakood,kogus
            from myyk
            order by 1
            $ct$,$ct$
            select distinct tootjakood
            from myyk
            order by 1
            $ct$
        ) as (
            kuupaev date,
            %4$s
        );$f$,

        replace(voter_list, ' ', ' + '),
        replace(voter_list, ' ', ', '),
        '',
        replace(voter_list, ' ', ' integer, ') || ' integer'  -- 4.
    ));
end; $do$;

select * from pivot;

使用 Postgres 9.1。

【问题讨论】:

    标签: postgresql pivot-table plpgsql postgresql-9.1


    【解决方案1】:

    在 DO 块体的底部插入一个异常处理程序。您可以默默地忽略错误并创建虚拟pivot 表:

    ...
    exception
        when others then
            drop table if exists pivot;
            create table pivot ("No data" text);
    end; $do$;
    

    或使用您自己的错误消息引发异常:

    ...
    exception
        when others then
            drop table if exists pivot;
            raise exception 'There is no data in the source dataset.'
    end; $do$;
    

    你也可以使用 if-then-else 语句:

    ...
    drop table if exists pivot;
    
    if (select count(*) from myyk) > 0 then 
        voter_list := (
            select string_agg(distinct tootjakood, ' ' order by tootjakood) from myyk
            );
        ...
        ...
    else
        create table pivot ("No data" text);
    end if;
    end; $do$;
    

    【讨论】:

    • 我不喜欢使用异常处理程序。在这种情况下,如何检查 voter_list 是否为空或 myyk 表是否不包含记录并返回空表?或者如果没有行,是否可以强制交叉表返回空表?
    • stackoverflow.com/questions/35267989/…有相关问题对于空表检查,如果crosstab不能返回空表,是否可以使用plpgsql IF命令返回空表?
    • 谢谢。为了避免额外的表扫描,我使用了if voter_list is null then create temp table pivot ("No data" text) on commit drop; return; end if; 可以吗?
    • 是的,return 可以避免在没有数据的时候出错。
    猜你喜欢
    • 2010-11-04
    • 2010-12-16
    • 2019-02-21
    • 2016-05-09
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多