2017-07-09 13 views
0

取引の一覧に契約テーブルをリンクして、払い過ぎがあるかどうかを確認しようとしていますが、データに有効な一意の共有キーがありません。ここでPostgresqlの日付範囲と集計結果が重複しています

が私の契約テーブルの例です:

| 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で例えば契約)重複しているので、私は」することができます各契約の各月のすべての取引をリンクするだけです。これは、重複期間中に取引を二重にカウントすることを意味するためです。

同様に、契約期間(例えば、supplier_bの取引)に含まれる取引が含まれるため、max()とmin()は使用できません。私の知る限り、これらのテーブルをリンクするための最良の方法は、それがこのようなものを見えるようにビューに私の契約テーブルをロールアップすることです言うことができるように

...に対する値として

| 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_idsupplier_idmonthの3つの列で取引をリンクするのは簡単です。

問題は、新しいビューを作成する方法を理解することができないことです。私はサブクエリを使用して日付範囲を月のリストに入れてからsum(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

あなたは得たい結果の例を教えてください。 – Abelisto

答えて

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にマージしました。

About generate_series() function

関連する問題