简体   繁体   English

Postgres动态数据透视表

[英]Postgres Dynamic Pivot Table

I am needing to create this table (not really for donuts). 我需要创建该表(不是真正的甜甜圈)。

I basically want to output the time to sell a product within a certain time frame. 我基本上想输出在特定时间范围内销售产品的时间。

The time frame is defined in a table and needs to be able to be reconfigured (dropped and recreated) without breaking the query. 时间范围是在表中定义的,并且需要能够重新配置(删除和重新创建)而不中断查询。

That is to say the time_frames we are interested in monitoring will, by design, change often. 也就是说,我们有意监视的time_frames会根据设计经常更改。 Today there may be 4 timeframes (6h ea) defined, tomorrow I might make just one (24h), the next day there may be 12 rows(2 ea). 今天可能定义了4个时间范围(6h ea),明天我可能只定义了一个(24h),第二天可能有12行(2 ea)。 The time_frames might also be of differing lengths. time_frames的长度也可能不同。 The columns would stay the same. 列将保持不变。

SQLFiddle 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  |
--  +---------+-------------+----------------+----------------+----------------+

I actually don't understand how time values appear in your output table, but if you want to count number of donuts sold in each time_frame, you can use this query: 我实际上不明白时间值如何显示在输出表中,但是如果您要计算每个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 sql小提琴演示

You can't make dynamic number of time_frames, though, because you cannot make dynamic columns in output in PostgreSQL. 但是,由于无法在PostgreSQL的输出中创建动态列,因此无法动态创建time_frames数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM