如何在动态数据透视表上保留列名
how to preserve column names on dynamic pivot
销售数据包含可以包含任何字符的动态产品名称。
动态枢轴 table 是基于来自的示例创建的
Crosstab with a large or undefined number of categories
translate() 用于去除不良字符。
结果枢轴 table 中的列名称已损坏:删除了缺失的字符和空格。
如何 return 具有与源数据中相同列名的数据?
我尝试使用
quote_ident(productname) as tootjakood,
而不是
'C'||upper(Translate(productname,'Ø. &/+-,%','O')) as tootjakood,
但是 return 错误
错误:列“Ø,12.3/3mm”不存在
测试用例:
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,
'C'||upper(Translate(productname,'Ø. &/+-,%','O')) 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。
你应该使用双引号。因为你是用空格来标识列分隔符,所以你应该把列名中的空格去掉(或者改变分隔符的标识方式)。
有
...
select saledate as kuupaev,
format ('"%s"', replace (upper(productname), ' ', '')) as tootjakood,
sum(quantity)::int as kogus
from sales
...
您将获得:
kuupaev | /3,2M- | +-3,4%/3MM | O12.3/3MM
------------+--------+------------+-----------
2016-01-01 | | 52 | 2
2016-01-03 | 246 | |
(2 rows)
销售数据包含可以包含任何字符的动态产品名称。
动态枢轴 table 是基于来自的示例创建的 Crosstab with a large or undefined number of categories
translate() 用于去除不良字符。
结果枢轴 table 中的列名称已损坏:删除了缺失的字符和空格。 如何 return 具有与源数据中相同列名的数据? 我尝试使用
quote_ident(productname) as tootjakood,
而不是
'C'||upper(Translate(productname,'Ø. &/+-,%','O')) as tootjakood,
但是 return 错误
错误:列“Ø,12.3/3mm”不存在
测试用例:
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,
'C'||upper(Translate(productname,'Ø. &/+-,%','O')) 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。
你应该使用双引号。因为你是用空格来标识列分隔符,所以你应该把列名中的空格去掉(或者改变分隔符的标识方式)。
有
...
select saledate as kuupaev,
format ('"%s"', replace (upper(productname), ' ', '')) as tootjakood,
sum(quantity)::int as kogus
from sales
...
您将获得:
kuupaev | /3,2M- | +-3,4%/3MM | O12.3/3MM
------------+--------+------------+-----------
2016-01-01 | | 52 | 2
2016-01-03 | 246 | |
(2 rows)