使用LEFT OUTER JOIN从其他表更新表值

时间:2018-12-05 17:43:34

标签: sql sql-server sql-server-2008 left-join

我正在用更多详细信息和我尝试过的东西更新我的问题。

我有两个表Product_Staging和Product。该表的内容如下。

Product_Staging:

Account_No         Product_No        Cur_Revenue             Prev_Revenue
12                 AB                5.0                     3.0
13                 BC                4.0                     4.0
15                 DF                10.0                    7.5
17                 BC                NULL                    NULL
18                 AZ                NULL                    NULL 

产品:

Account_No         Product_No        Cur_Revenue             Prev_Revenue
12                 AB                1.0                     3.0
13                 BC                4.0                     5.0
16                 DF                10.0                    17.5
17                 CG                5.0                     6.0
18                 AZ                NULL                    NULL 

我需要根据以下条件更新产品表的Cur_Revenue和Prev_Revenue字段。

1)当两个表中的Account_No和Product_No之间存在匹配项并且收入值不同时,应在Product表中更新Product_Staging的Cur_Revenue和Prev_Revenue。

2)当Product中存在Account_No和Product_No的特定组合的记录,并且在Product_Staging表中不存在该记录时,应将Product的Cur_Revenue和Prev_Revenue设置为NULL。

3)如果两个表中的Account_No和Product_No之间都匹配并且收入值相同,则不应更新Product表。

4)当产品中某个特定Account_No和Product_No的记录中的收入值为NULL,并且如果Product_Staging中不存在Account_No和Product_No组合的记录,则不应更新该产品记录。

更新后的产品:

Account_No         Product_No        Cur_Revenue             Prev_Revenue
12                 AB                5.0                     3.0 (Updated from Product_Staging)
13                 BC                4.0                     4.0 (Updated from Product_Staging)
16                 DF                                            (Cleared)
17                 CG                NULL                   NULL                            (Cleared)
18                 AZ                NULL                   NULL (Not Updated)

下面的查询正在努力实现#1和#2的结果,但不适用于#3和#4,这就是我在努力的地方。

update p SET
p.Cur_Revenue =  ps.Cur_Revenue,
p.Prev_Revenue = ps.Prev_Revenue
from Product p
LEFT JOIN Product_Staging ps on
    p.Account_No= ps.Account_No AND p.Product_No = ps.Product_No

即使某个Account_No和Product_No组合的Product和Product_Staging表中的收入值相同,此查询也会更新Product。另外,当收入值为NULL并且Product_Staging表中没有记录时,我不确定如何跳过产品中的记录。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

您看起来很接近,但条件必须放在SET组件中。 LEFT-JOIN没问题,只是您要基于...进行更新...这是您的最终查询。

update p SET
      p.Cur_Revenue = ps.Cur_Revenue,
      p.Prev_Revenue = ps.Prev_Revenue
   from 
      Product p
         LEFT JOIN Product_Staging ps 
            on p.Account_No = ps.Account_No 
           AND p.Product_No = ps.Product_No
   where
          -- This is for condition #3
          (     NOT ps.Product_No IS NULL
           AND (    p.Cur_Revenue <> ps.Cur_Revenue
                 OR p.Prev_Revenue <> ps.Prev_Revenue ))
     OR   -- This is for condition #4
          (     ps.Product_No IS NULL
           AND p.Cur_Revenue IS NULL
           AND p.Prev_Revenue IS NULL )

澄清,让您的头部不会受伤。

根据示例,只有2个条件可以更新“产品”表... 1和2。

1-两个表中的匹配项和收入都不同,请使用登台中的值进行更新。

2-当暂存中没有匹配记录时,将生产设置为NULL。

update p SET
      p.Cur_Revenue = ps.Cur_Revenue,
      p.Prev_Revenue = ps.Prev_Revenue
   from 
      Product p
         LEFT JOIN Product_Staging ps 
            on p.Account_No = ps.Account_No 
           AND p.Product_No = ps.Product_No

因此,请考虑一下。您对匹配的“产品”和“帐户”具有暂存关系。因此,在最坏的情况下,您要么有比赛,要么没有。如果没有匹配项,则登台表中的所有值均为NULL。如果存在匹配项,则无论其暂存值是多少,都希望更新。因此,SET直接到达该列。根据#1,如果有匹配项,则更新(您有一个值,很好)。对于#2,如果没有匹配项,则将其设置为null(没有匹配项,则值为null)。因此,我们甚至都不需要这种情况/时间。

现在,让我们阐明您的条件3和4,以便在不需要时不进行更新。首先,#3,有一个匹配项,收入是相同的...

3)当两个表中的Account_No和Product_No之间匹配且收入值相同时,则不应更新Product表。请注意,整个部分都用括号括起来。 “ NOT ps.Product_No IS NULL”表示DID找到与登台表的匹配项。在这种情况下,我们只希望在收入中的任何一个不相同时进行更新。因此,这与1上的括号进行“与”运算,或者其他收益不相同(因此<>)。因此,如果我们有一条匹配的记录,并且其中一个(或两个)金额不同,则必须对其进行更新。

(      NOT ps.Product_No IS NULL
   AND (   p.Cur_Revenue <> ps.Cur_Revenue
        OR p.Prev_Revenue <> ps.Prev_Revenue ))

4)当产品中某个特定Account_No和Product_No的记录中的收入值为NULL,并且如果Product_Staging中不存在Account_No和Product_No组合的记录,则不应更新该产品记录。

此处,第一个匹配在登台中不匹配,因此为“ ps.Product_No IS NULL”,而且,如果登台中没有匹配项,那么收入字段的BOTH也必须都为空以不需要更新。因此,我要将这两个收入都设为AND。如果一个或两个都具有值,则您要根据#2条件将其更改为null来更新。

OR (     ps.Product_No IS NULL
     AND p.Cur_Revenue IS NULL
     AND p.Prev_Revenue IS NULL )

希望这可以防止您的头部受伤:)

答案 1 :(得分:0)

再次阅读您的问题后,我认为您需要将一个连接条件移至case进行更新。我仍然对#2和Product2的位置感到困惑。

update p SET
    p.Cur_Revenue = case 
                        when p.Product_No = ps.Product_No and p.Cur_Revenue != p.Prev_Revenue then ps.Cur_Revenue       --1
                        when ps.Account_No is null or ps.Product_No != p.Product_No then NULL                           --2
                        when p.Product_No = ps.Product_No and p.Cur_Revenue = p.Prev_Revenue then p.Cur_Revenue         --3
                        when p.Product_No != ps.Product_No then p.Cur_Revenue                                           --4
                        else p.Cur_Revenue                                                                              --catch all
                    end
    ,p.Prev_Revenue =case 
                        when p.Product_No = ps.Product_No and p.Cur_Revenue != p.Prev_Revenue then ps.Prev_Revenue      --1
                        when ps.Account_No is null or ps.Product_No != p.Product_No then NULL                           --2
                        when p.Product_No = ps.Product_No and p.Cur_Revenue = p.Prev_Revenue then p.Prev_Revenue        --3
                        when p.Product_No != ps.Product_No then p.Prev_Revenue                                          --4
                        else p.Prev_Revenue                                                                         --catch all
                    end
from Product p
INNER JOIN Product_Staging ps on
    p.Account_No= ps.Account_No