Postgres动态数据透视表

时间:2013-08-30 15:06:49

标签: sql postgresql time pivot postgresql-9.2

我需要创建这个表(不是真的用于甜甜圈)。

我基本上想要输出在特定时间范围内销售产品的时间。

时间范围在表中定义,需要能够在不破坏查询的情况下重新配置(删除和重新创建)。

也就是说,我们对监控感兴趣的时间框架将经常改变。今天可能有4个时间帧(6h ea)定义,明天我可能只做一个(24h),第二天可能有12行(2 ea)。 time_frames也可能有不同的长度。列将保持不变。

SQLFiddle

CREATE TABLE time_frame 
  (
    id SERIAL NOT NULL
    ,start_time time
    ,end_time time
    ,PRIMARY KEY(id)
  );

CREATE TABLE donut_sales 
  (
    saleid SERIAL NOT NULL
    ,donutid INT
    ,donutname TEXT
    ,stocked timestamp
    ,sold timestamp
    ,PRIMARY KEY (saleid)
  );

--  SELECT * FROM FANCY_PIVOT_TABLE_I_DONT_UNDERSTAND
--  +---------+-------------+----------------+----------------+----------------+
--  | donutid | donutname   |  time_frame_1  |  time_frame_2  |  time_frame_3  |
--  +---------+-------------+----------------+----------------+----------------+
--  |       1 | sprinkles   |      00:17:66  |      00:17:66  |      00:17:66  |
--  |       2 | jelly       |      00:17:66  |      00:17:66  |      00:17:66  |
--  |       3 | custard     |      00:17:66  |      00:17:66  |      00:17:66  |
--  +---------+-------------+----------------+----------------+----------------+

1 个答案:

答案 0 :(得分:1)

我实际上不明白时间值在输出表格中的显示方式,但是如果你想计算每个time_frame中出售的甜甜圈数量,你可以使用这个查询:

select
    ds.donutid, ds.donutname,
    sum(case when ts.id = 1 then 1 else 0 end) as time_frame_1,
    sum(case when ts.id = 2 then 2 else 0 end) as time_frame_2,
    sum(case when ts.id = 3 then 3 else 0 end) as time_frame_3,
    sum(case when ts.id = 4 then 4 else 0 end) as time_frame_4
from donut_sales as ds
    inner join time_frame as ts on
        ts.start_time <= ds.sold::time and ts.end_time > ds.sold::time
group by ds.donutid, ds.donutname
order by ds.donutid

sql fiddle demo

但是,您无法生成动态的time_frames数,因为您无法在PostgreSQL的输出中创建动态列。