create or replace function xtab (tablename varchar, rowc 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||','||colc||','||cellc||' from '||tablename||' group by 1,2 order by 1,2'',
''select distinct '||colc||' from '||tablename||' order by 1''
)
as ct (
'||rowc||' varchar,'||columnlist||'
);';
return dynsql2;
end
$$;
现在我可以调用这个函数:
select xtab('globalpayments','month','currency','(sum(total_fees)/sum(txn_amount)*100)::decimal(48,2)','text');
这将返回(因为函数的返回类型是varchar):
select * from crosstab (
'select month,currency,(sum(total_fees)/sum(txn_amount)*100)::decimal(48,2)
from globalpayments
group by 1,2
order by 1,2'
, 'select distinct currency
from globalpayments
order by 1'
) as ct ( month varchar,CAD text,EUR text,GBP text,USD text );
我该如何让这个函数不仅生成动态交叉表的代码,还能执行结果?也就是说,当我手动复制/粘贴/执行时得到的结果是这样的。但我希望它能在没有额外步骤的情况下执行:函数应该组装动态查询并执行它:
编辑1
这个函数接近了我的需求,但我需要它返回的不止是第一行记录的第一列。
摘自:有没有办法在PostgreSQL中字符串值内执行查询(类似于eval)?
create or replace function eval( sql text ) returns text as $$
declare
as_txt text;
begin
if sql is null then return null ; end if ;
execute sql into as_txt ;
return as_txt ;
end;
$$ language plpgsql
用法:select * from eval($$select * from analytics limit 1$$)
然而,它只返回第一行的第一列:
eval
----
2015
当实际结果看起来像这样:
Year, Month, Date, TPV_USD
---- ----- ------ --------
2016, 3, 2016-03-31, 100000
execute immediate 'select 1'
而不会出错... :( - skilbjoEXECUTE IMMEDIATE
不会返回行,并且不适用于您的问题,因为您显然想要检索结果行。 - Erwin Brandstetter