从动态数据透视表返回空数据是没有数据

Returning empty data from dynamic pivot is there is no data

下面来自 的代码用于创建动态枢轴 table。

如果源 table 不包含任何数据,则会发生 sql 错误,因为创建 table 列列表以逗号结尾(没有数据透视列)。 如何解决此问题以便返回空 table?

要重现,删除插入命令

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。

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

...
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$;