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.
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
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.
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.