具有生成列的PostgreSQL查询

具有生成列的PostgreSQL查询,sql,postgresql,pivot,crosstab,Sql,Postgresql,Pivot,Crosstab,我有一个如下所示的模式,我想运行一个查询,在该查询中,我在points表的每一行的输出中都会得到一列 因此,对于每一个使用量行,我想将使用量乘以参考点的数量,然后将其相加,并按人分组。对于示例数据,我希望输出如下所示: Name | foo | bar | baz -------|------|------|------ Scott | 10.0 | 24.0 | 0.0 Sam | 0.0 | 0.0 | 46.2 以下是模式/数据: 创建表点 ident

我有一个如下所示的模式,我想运行一个查询,在该查询中,我在points表的每一行的输出中都会得到一列

因此,对于每一个使用量行,我想将使用量乘以参考点的数量,然后将其相加,并按人分组。对于示例数据,我希望输出如下所示:

 Name  | foo  | bar  | baz  
-------|------|------|------
 Scott | 10.0 | 24.0 | 0.0  
 Sam   | 0.0  | 0.0  | 46.2   
以下是模式/数据:

创建表点 ident int主键不为空, abbrev VARCHAR不为空, 实际金额不为空 ; 创建表用法 ident int主键不为空, 名称VARCHAR不为空, 点标识整数引用点标识, 实际金额 ; 插入点标识、缩写、金额值 1“foo”,1.0, 2“巴”,2.0, 3,'baz',3.0; 插入使用标识、名称、点数、金额值 1,“斯科特”,1,10, 2,“斯科特”,2,12, 3,“山姆”,3,3.4, 4,‘山姆’,3,12; 我正在使用PostgreSQL 9.2.8

数据只是样本。实际使用率表中有数千行,而points表中可能有十几行。这里真正的目的是我不想硬编码所有的点求和,因为我在许多函数中使用它们

select 
t1.name,
sum(case when t2.abbrev='foo' then t1.amount*t2.amount else 0 end) as foo,
sum(case when t2.abbrev='bar' then t1.amount*t2.amount else 0 end) as bar,
sum(case when t2.abbrev='baz' then t1.amount*t2.amount else 0 end) as baz
from usage t1 inner join points t2 on t1.points_id=t2.ident
group by t1.name;
SQLFiddle示例:

对于动态情况,请使用以下PostgreSQL函数:

create or replace function sp_test()
returns void as
$$

declare cases character varying;
declare sql_statement text;
begin

select string_agg(concat('sum(case when t2.abbrev=','''',abbrev,'''',' then t1.amount*t2.amount else 0 end) as ', abbrev),',') into cases from points;

drop table if exists temp_data;

sql_statement=concat('create temporary table temp_data as select 
t1.name,',cases ,' 
from usage t1 inner join points t2 on t1.points_id=t2.ident
group by t1.name ');

execute sql_statement;

end;
$$
language 'plpgsql';
函数使用临时表存储动态列数据

按以下方式调用函数以获取数据:


从sp_测试中选择*;从临时数据中选择*

这是特定于所示数据的。我只是给出一些示例数据。有数千个“用法”行和十几个“点”行。需要有活力。