带有生成列的PostgreSQL查询 [英] PostgreSQL query with generated columns

查看:74
本文介绍了带有生成列的PostgreSQL查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的架构,我想运行一个查询,在其中我为points表的每一行在输出中获得一列.

I have a schema as show like the below, and I want to run a query where I get a column in the output for every row of the points table.

因此,对于每一行usage,我想将使用率的amount乘以引用的points_idamount,然后将其相加并逐个分组.因此,对于示例数据,我希望输出如下所示:

So for each usage row I want to multiply the amount of the usage times the amount for the referenced points_id, and then sum that up and group by person. So for the example data I'd want output that looked like this:

 Name  | foo  | bar  | baz  
-------|------|------|------
 Scott | 10.0 | 24.0 | 0.0  
 Sam   | 0.0  | 0.0  | 46.2   

以下是架构/数据:

CREATE TABLE points (
   ident int primary key NOT NULL,
   abbrev VARCHAR NOT NULL,
   amount real NOT NULL
);

CREATE TABLE usage (
  ident int primary key NOT NULL,
  name VARCHAR NOT NULL,
  points_id integer references points (ident),
  amount real
);

INSERT INTO points (ident, abbrev, amount) VALUES
  (1, 'foo', 1.0),
  (2, 'bar', 2.0),
  (3, 'baz', 3.0);

INSERT INTO usage (ident, name, points_id, amount) VALUES 
  (1, 'Scott', 1, 10),
  (2, 'Scott', 2, 12),
  (3, 'Sam', 3, 3.4),
  (4, 'Sam', 3, 12);

我正在使用PostgreSQL 9.2.8

I'm using PostgreSQL 9.2.8

数据仅是示例.实际的usage表中有数千行,而points表中可能有十几行.真正的目的是我不想对所有points求和进行硬编码,因为我在许多函数中都使用了它们.

The data is just sample. There are thousands of rows in the real usage table and probably a dozen in the points table. The real intent here is I don't want to hardcode all the points summations as I use them in many functions.

推荐答案

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;

SQL Fiddle示例: http://sqlfiddle.com/#!15/cc84a/6 ;

SQL Fiddle Example:http://sqlfiddle.com/#!15/cc84a/6;

在动态情况下使用以下PostgreSQL函数:

Use following PostgreSQL function for dynamic cases:

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';

函数使用临时表存储动态列数据.

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

Call function in following way to get data:

select * from sp_test(); select * from temp_data;

这篇关于带有生成列的PostgreSQL查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆