简体   繁体   中英

Update Table value from other table using LEFT OUTER JOIN

I am updating my question with more details and the things that I have tried on.

I have two tables Product_Staging and Product. The contents of the table are below.

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 

Product:

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 

I need to update the Product table's Cur_Revenue and Prev_Revenue fields based on the following conditions.

1) When there is a match between Account_No and Product_No in both tables and the revenue values are different, the Cur_Revenue and Prev_Revenue from Product_Staging should be updated in Product table.

2) When a record exists in Product for a certain combination of Account_No and Product_No and if it does not exists in Product_Staging table, the Cur_Revenue and Prev_Revenue from Product should be set to NULL.

3) When there is match between Account_No and Product_No in both tables and the revenue values are same, the Product table should NOT be updated.

4) When a record exists in Product for a particular Account_No and Product_No with revenue values as NULL and if there is no record exists in Product_Staging for the Account_No and Product_No combination, the Product record should NOT be updated.

Product After Update:

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)

The below query is working to achieve the results of #1 and #2, but not for #3 and #4 and this is where I am struggling.

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

This query is updating Product even when the revenue values are same in Product and Product_Staging table for a certain Account_No and Product_No combination. Also, I am not sure how to skip the records from getting updated in Product when the revenue values are NULL and there is no record in Product_Staging table.

Can someone help?

You APPEAR to be pretty close, but the conditions need to be put in your SET component. The LEFT-JOIN is ok, just what are you updating based on... Here is a FINAL query for you.

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 )

CLARIFICATION so your head does not hurt.

There are only 2 conditions that your Product table should be updated per your example... 1 & 2.

1 - Match in BOTH tables and revenues are different, update with values from staging.

2 - When NO matching record in staging, set production to 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

So lets think about it. You have a left-join to the staging on the matching Product and Account. So worst case scenario you either have a match or you don't. If you do NOT have a match, then all values in the staging table are NULL. If there IS a match, you want to update whatever its staging value is. So the SET is directly to that column. Per #1, if a match, update (you have a value, good). Per #2, if NO match, set to null (no match, the values are null). So we don't even NEED the case/when condition.

Now, lets clarify your conditions 3 & 4 to NOT update where not necessary. First, #3, there IS a match and revenues are the same...

3) When there is match between Account_No and Product_No in both tables and the revenue values are same, the Product table should NOT be updated. Notice the entire portion is wrapped in parentheses. the "NOT ps.Product_No IS NULL" means it DID find a match to the staging table. When that is the case, we only want to update when EITHER of the revenues are not the same. So this is ANDed with a parentheses on either 1 OR the other revenue is not the same (hence <> ). So, if we have a matching record and ONE (or both) of the amounts are different, we must update it.

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

4) When a record exists in Product for a particular Account_No and Product_No with revenue values as NULL and if there is no record exists in Product_Staging for the Account_No and Product_No combination, the Product record should NOT be updated.

Here, first hit is NO match in staging, hence "ps.Product_No IS NULL", but also, if no match in staging, BOTH of the revenue fields must also be null to not require the update. So I am ANDing both of those revenues to null. If either one or both have a value, you want to change them TO null per your #2 condition to update.

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

Hopefully this can prevent your head from hurting now :)

After reading your question again, I think you need to move one join condition to a case for the update. I'm still confused about #2 though and where Product2 is.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM