你不能有一个“动态”的数据透视,因为查询的所有列的数量、名称和数据类型必须在查询实际执行之前被数据库知道(即在解析时)时间)。
我发现将内容聚合成 JSON 更容易处理。
select customer_number,
jsonb_object_agg(label, value) as props
from the_table
group by customer_number
如果你的前端可以直接处理 JSON 值,你可以到此为止。
如果您确实需要每个属性一列的视图,您可以从 JSON 值中获取它们:
select customer_number,
props ->> 'address' as address,
props ->> 'phone' as phone,
props ->> 'email' as email
from (
select customer_number,
jsonb_object_agg(label, value) as props
from the_table
group by customer_number
) t
我发现添加新属性时这更容易管理。
如果您需要一个带有所有标签的视图,您可以创建一个存储过程来动态创建它。如果不同标签的数量不会经常变化,这可能是一个解决方案:
create procedure create_customer_view()
as
$$
declare
l_sql text;
l_columns text;
begin
select string_agg(distinct format('(props ->> %L) as %I', label, label), ', ')
into l_columns
from the_table;
l_sql :=
'create view customer_properties as
select customer_number, '||l_columns||'
from (
select customer_number, jsonb_object_agg(label, value) as props
from the_table
group by customer_number
) t';
execute l_sql;
end;
$$
language plpgsql;
然后使用以下命令创建视图:
call create_customer_view();
在你的代码中使用:
select *
from customer_properties;
您可以安排该过程定期运行(例如,通过 Linux 上的 cron 作业)