我正在尝试将合同表链接到交易列表,以查看是否存在任何超支,但是,数据没有有效的唯一共享密钥。
这是我的合约表的一个例子:
| buyer_id | supplier_id | start_date | end_date | contract_value |
| buyer_a | supplier_a | 2015-01-01 | 2017-01-01 | 240000 |
| buyer_a | supplier_a | 2016-01-01 | 2016-06-01 | 6000 |
| buyer_a | supplier_b | 2015-01-01 | 2015-12-31 | 100000 |
| buyer_a | supplier_b | 2017-01-01 | 2017-12-31 | 100000 |
这是我的消费表的一个例子:
| buyer_id | supplier_id | month | trans_value |
| buyer_a | supplier_a | 2015-01-01 | 1230.12 |
| buyer_a | supplier_a | 2015-02-01 | 1735.98 |
| buyer_a | supplier_a | 2015-03-01 | 2242.02 |
由于合约日期重叠(例如与supplier_a的合约),我不能只链接每份合约每个月的所有交易,因为这意味着我在此期间重复计算交易。交叠。
同样,我不能使用max()和min(),因为在合同之间发生的任何交易(例如那些与supplier_b的交易)都会被包括在内。
据我所知,链接这些表的最佳方法是将我的合约表汇总到一个视图中,以便它看起来像这样......
| buyer_id | supplier_id | month | value |
| buyer_a | supplier_a | 2015-01-01 | 10000 |
| buyer_a | supplier_a | 2015-02-01 | 10000 |
| buyer_a | supplier_a | 2015-03-01 | 10000 |
| buyer_a | supplier_a | 2015-04-01 | 10000 |
| buyer_a | supplier_a | 2015-05-01 | 10000 |
| buyer_a | supplier_a | 2015-06-01 | 10000 |
| buyer_a | supplier_a | 2015-07-01 | 10000 |
只要每个月的值是合同的总和份额,就可以轻松地将buyer_id
,supplier_id
和month
唯一的三重列上的交易关联起来,然后我就可以确定任何超支。
问题在于我甚至无法开始研究如何构建新视图。我觉得我应该可以使用子查询来解包'将日期范围分为几个月的列表,然后是总和(case()),但我的深度不同。
PS。我无法控制这些数据的发布方式,因此无法从源头上改进数据。
编辑:我希望能够创建这样的输出,然后我可以将其放入图表中以显示超支:
| buyer_id | supplier_id | month | monthly_con_val | trans_value |
| buyer_a | supplier_a | 2015-01-01 | 10000 | 34000 |
| buyer_a | supplier_a | 2015-02-01 | 10000 | 10000 |
| buyer_a | supplier_a | 2015-03-01 | 50000 | 8000 |
| buyer_a | supplier_a | 2015-04-01 | 50000 | 14000 |
| buyer_a | supplier_a | 2015-05-01 | 50000 | 4000 |
| buyer_a | supplier_a | 2015-06-01 | 10000 | 3000 |
| buyer_a | supplier_a | 2015-07-01 | 10000 | 3000 |
答案 0 :(得分:1)
像
这样的东西with
-- Sample data
contracts(bs_id, start_date, end_date, contract_value) as (values
(1, '2015-01-01'::date, '2017-01-01'::date, 240000),
(1, '2016-01-01'::date, '2016-06-01'::date, 6000)),
spending(bs_id, month, trans_value) as (values
(1, '2015-01-01'::date, 1230.12),
(1, '2015-02-01'::date, 1735.98),
(1, '2016-05-01'::date, 5689.01)),
-- End of sample data
contracts_monthly as (
select
bs_id,
month::date,
sum(
contract_value / (
(extract(year from end_date)*12 + extract(month from end_date)) -
(extract(year from start_date)*12 + extract(month from start_date)))) as monthly_con_val
from contracts, generate_series(start_date, end_date, interval '1 month') as month
group by bs_id, month
order by bs_id, month)
select
*
from
contracts_monthly left join spending using (bs_id, month);
为了使示例更紧凑,我将列buyer_id | supplier_id
合并到单个列bs_id
中。