多个连接在不同列的同一个表上

时间:2015-12-01 08:42:56

标签: sql oracle

我正在尝试构建以下场景的SQL逻辑:

我有一个名为的表:产品有(Item_Id,Product_Holder,Price,Month) 和另一个表Sales :( Item_Id,Issued_from,Sent_to,Impact_Value,Month)

如果说我们在以下产品中有记录:

Item_id | Product_Holder | Price  | Month
x       |  B123          |   10   |   2
x       |  Z555          |   8    |   3
y       |  A444          |   15   |   2
y       |  K000          |   10   |   3

Item_id | Issued_from    | Sent_to| Impact_Value | Month | 
x           B123            Z555                   3         
y           A444            K000                   3      

列:Product_Holder,Issued_from,Sent_to具有相同类型的值,因此您可以加入这些值。

我尝试使用 Item_id,Month和Issued_from 加入 Item_id,Month和Product_Holder ,然后尝试 Sent_to 的其他类似加入。但是对于我来说如何计算这些值是不合理的,以便分别用-2和-5填充 Impact_Value 列。

因此从B123到Z555的销售产生了-2 从A444到K000的销售导致-5

修改

这与访问上一行无关。一个Item可以属于许多具有不同价格的Product_Holders。在Sales表中,当项目从Product_Holder(Issue_from)传输到另一个Product_Holder(Sent_to)时,Impact_Value将更改。我想在Impact_Value列中计算此值。

1 个答案:

答案 0 :(得分:0)

完全基于您提供的数据,这是一种方法:

with products as (select 'x' Item_id, 'B123' Product_Holder, 10 Price, 2 Mnth from dual union all
                  select 'x' Item_id, 'Z555' Product_Holder, 8 Price, 3 Mnth from dual union all
                  select 'y' Item_id, 'A444' Product_Holder, 15 Price, 2 Mnth from dual union all
                  select 'y' Item_id, 'K000' Product_Holder, 10 Price, 3 Mnth from dual),
        sales as (select 'x' item_id, 'B123' issued_from, 'Z555' sent_to, null impact_value, 3 mnth from dual union all
                  select 'y' item_id, 'A444' issued_from, 'K000' sent_to, null impact_value, 3 mnth from dual)
select sls.item_id,
       sls.issued_from,
       sls.sent_to,
       sum(case when prd.product_holder = issued_from then -1 * prd.price
                else prd.price
           end) impact_value,
       sls.mnth
from   products prd
       inner join sales sls on (prd.item_id = sls.item_id
                                and (prd.product_holder = sls.issued_from
                                     or (prd.product_holder = sls.sent_to
                                         and prd.mnth = sls.mnth)))
group by sls.item_id,
         sls.issued_from,
         sls.sent_to,
         sls.mnth;

ITEM_ID ISSUED_FROM SENT_TO IMPACT_VALUE       MNTH
------- ----------- ------- ------------ ----------
y       A444        K000              -5          3
x       B123        Z555              -2          3

要更新销售表,我会这样做:

merge into sales tgt
using (select sls.item_id,
              sls.issued_from,
              sls.sent_to,
              sum(case when prd.product_holder = issued_from then -1 * prd.price
                       else prd.price
                  end) impact_value,
              sls.mnth
       from   products prd
              inner join sales sls on (prd.item_id = sls.item_id
                                       and (prd.product_holder = sls.issued_from
                                            or (prd.product_holder = sls.sent_to
                                                and prd.mnth = sls.mnth)))
       group by sls.item_id,
                sls.issued_from,
                sls.sent_to,
                sls.mnth) src
  on (tgt.item_id = src.item_id
      and tgt.issued_from = src.issued_from
      and tgt.sent_to = src.sent_to
      and tgt.mnth = src.month) -- assuming these columns are enough to define a unique row in the sales table
when matched then
update set tgt.impact_value = src.impact_value;

N.B。您可能需要计算出在sales表中指定的月份或之前的最新的issued_from行,但这是一个由您完成的练习。

我还希望在您的真实表中,您有一个更好的销售日期标识符,而不仅仅是一个月的数字。例如。一个月和一年,甚至更好的实际日期!