【问题标题】:Update Table value from other table using LEFT OUTER JOIN使用 LEFT OUTER JOIN 从其他表更新表值
【发布时间】:2018-12-08 11:03:12
【问题描述】:

我正在更新我的问题,提供更多细节和我尝试过的东西。

我有两个表 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 

我需要根据以下条件更新 Product 表的 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) 如果 Product 中存在特定 Account_No 和 Product_No 的记录且收入值为 NULL,并且如果 Product_Staging 中不存在 Account_No 和 Product_No 组合的记录,则不应更新 Product 记录。

更新后的产品:

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 表中没有记录时,我不确定如何跳过在 Product 中更新的记录。

有人可以帮忙吗?

【问题讨论】:

  • 您可能应该包括您尝试完成这项工作的内容,以免它看起来像家庭作业问题。
  • 另外,请仔细考虑您的要求。如果表A有一行非空值的字段要更新到表B,但表B没有匹配表A的行怎么办?如果表 A 在更新字段中有一个 NULL,但表 B 有一行,应该怎么办? TL;DR - 如果您遇到意外但可预测的情况,请确保您知道该怎么做。
  • 为了更加清晰,我去掉了表 A 和表 B 的命名法,并用我尝试过的内容更新了原始帖子。
  • 你能解释一下吗 * 当 Product2 中存在 Account_No 和 Product_No 的特定组合的记录,如果 Product_Staging 表中不存在该记录,则 Product2 的 Cur_Revenue 和 Prev_Revenue 应设置为 NULL。* ?什么是product2?
  • 对不起,这只是产品表。此表是 Salesforce Product 对象的副本,在 Salesforce 中名称为 Product2。

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


【解决方案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 )

澄清一下,这样你的头就不会受伤了。

根据您的示例,您的 Product 表仅应更新 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)。所以我们甚至不需要 case/when 条件。

现在,让我们澄清您的条件 3 和 4,以便在不必要的情况下不更新。首先,#3,有一个匹配,收入是一样的......

3) 当两个表中的 Account_No 和 Product_No 匹配并且收入值相同时,不应更新 Product 表。请注意,整个部分都用括号括起来。 “NOT ps.Product_No IS NULL”表示它确实找到了与临时表的匹配项。在这种情况下,我们只想在收入不一样时更新。所以这是用括号与 1 或其他收入不一样(因此 )。因此,如果我们有匹配的记录并且其中一个(或两个)金额不同,我们必须更新它。

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

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

这里,第一次命中是暂存中不匹配,因此“ps.Product_No IS NULL”,而且,如果暂存中不匹配,则两个收入字段也必须为空,才不需要更新。所以我将这两项收入都归零。如果其中一个或两个都有值,则您希望根据要更新的#2 条件将它们更改为 null。

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

希望这可以防止你现在头疼:)

【讨论】:

  • 感谢您的回复。但是,如果旧值和新值相同,我的要求是不要重新更新记录。放宽此标准可能包括对表的数百万次重复更新。
  • @BalajiPooruli,请参阅修订 WHERE 子句以防止不必要的更新。
  • 谢谢,这超出了我的想象。我必须坐几分钟来消化它,然后尝试一下。感谢您的帮助。
  • @BalajiPooruli,我做了一个最终修订,最终查询完整,每个部分都有完整的解释,以帮助您跟进。
  • 感谢您的详细解释。这真的很有帮助。如果我理解正确,对于 #3 条件,我也可以检查 ps.Account_No,对吗?即,“NOT ( ps.Account_No IS NULL”因为 Account_No 和 Product_No 都匹配。
【解决方案2】:

再次阅读您的问题后,我认为您需要将一个联接条件移至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

【讨论】:

    猜你喜欢
    • 2020-01-10
    • 2012-06-21
    • 2014-10-23
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    相关资源
    最近更新 更多