简体   繁体   中英

How to compare three colums between source and target tables during merge or update operation

I have two tables, contribution(Member_number,Salyear,Salmonth,ReceiptDate) and contribution_update(Member_number,Salyear,Salmonth,ReceiptDate) . The column Receiptdate in the table contribution has null values. I want to update the column by comparing a combination of Member_Number , Salyear , Salmonth and where matches occur the Receiptdate gets updated.

I wrote the following code but it merges o values.

anyone with the idea on how to improve or rewrite the script.

i started with this code

MERGE INTO CONTRIBUTION cgt
USING (select MEMBER_NUMBER,SALYEAR,SALMONTH,RECEIVED_DATE from CONTRIBUTION_UPDATE  )cga
ON (cgt.MEMBER_NUMBER=cga.MEMBER_NUMBER AND cgt.SALYEAR=cga.SALYEAR AND cgt.SALMONTH=cga.SALMONTH)
WHEN matched then
update 
SET cgt.RECEIPTDATE=cga.RECEIVED_DATE;

then I discovered that the table contribution_update has duplicates (Gor message unable to get stable set of rows..). I recreated the table with no duplicates in it.

MERGE INTO Contribution M
      USING
      (Select Member_Number,Salyear,Salmonth,ReceiptDate From
(select MEMBER_NUMBER,SALYEAR,SALMONTH,RECEIptDATE,row_number() over (partition by MEMBER_NUMBER,SALYEAR,SALMONTH
 order by null ) as qry from Contribution_update)where qry=1) vu
              ON  (Vu.Member_Number = M.Member_Number and M.Salyear=Vu.Salyear and M.Salmonth=Vu.Salmonth )
  WHEN MATCHED
  THEN
  UPDATE
  SET  M.Receiptdate = Vu.ReceiptDate;
  WHERE M.Salyear=Vu.Salyear and M.Salmonth=Vu.Salmonth;

THE query is supposed to merge a number of rows in the target table.

You don't need that WHERE condition on the UPDATE part of your MERGE , it's taken care of by ON conditions. The WHEN MATCHED statement will only execute for matching rows - so the rows where MEMBER_NUMBER , SALYEAR and SALMONTH are the same between source and target.

Let's assume source - ContributionUpdate looks like this:

MEMBER_NUMBER SALYEAR     SALMONTH    RECEIVED_DATE
------------- ----------- ----------- -------------
1             2019        1           2019-10-10
2             2019        1           2019-10-20

And target - Contribution like this:

MEMBER_NUMBER SALYEAR     SALMONTH    RECEIVED_DATE
------------- ----------- ----------- -------------
1             2019        1           NULL

There's one matching row in the target, for member 1, year 2019, month 1. If you want to just update the matching years with RECEIVED_DATE from the source, this is enough:

MERGE INTO Contribution t
USING ContributionUpdate s
   ON s.MEMBER_NUMBER = t.MEMBER_NUMBER
  AND s.SALYEAR = t.SALYEAR
  AND s.SALMONTH = t.SALMONTH

WHEN MATCHED
THEN UPDATE 
 SET RECEIVED_DATE = s.RECEIVED_DATE;

(1 row affected)

If you wanted to also insert the one missing row from source into target (for member 2), you'd need to use WHEN NOT MATCHED BY TARGET , like so:

MERGE INTO Contribution t
USING ContributionUpdate s
   ON s.MEMBER_NUMBER = t.MEMBER_NUMBER
  AND s.SALYEAR = t.SALYEAR
  AND s.SALMONTH = t.SALMONTH

WHEN MATCHED
THEN UPDATE 
 SET RECEIVED_DATE = s.RECEIVED_DATE

WHEN NOT MATCHED BY TARGET
THEN INSERT
(
   MEMBER_NUMBER,
   SALYEAR      ,
   SALMONTH     ,
   RECEIVED_DATE
)
VALUES
(
   s.MEMBER_NUMBER,
   s.SALYEAR      ,
   s.SALMONTH     ,
   s.RECEIVED_DATE
);

(2 rows affected)

And as a result, the Contribution table will look like:

MEMBER_NUMBER SALYEAR     SALMONTH    RECEIVED_DATE
------------- ----------- ----------- -------------
2             2019        1           2019-10-20
1             2019        1           2019-10-10

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