简体   繁体   中英

SQL set operation for update latest record

I am facing a problem and cant find any solution to this. I have a source table (T) where I get data from field. The data may contain duplicate records with time stamp. My objective is to take the field data and store it into a final table (F) having the same structure. Before inserting I check whether key field exists or not in the F if yes I update the the record in F with the latest one from T. Other wise I Insert the record in F from T. This works fine as long as there is no duplicate record in T. In case T has two records of the same key with different time stamp. It always inserts both the record (In case the key is primary key the insert operation fails). I am using following code for the operation -

         IF EXISTS(SELECT * FROM [Final_Table] F, TMP_Source T WHERE T.IKEy =F.IKEY)
                begin 
                    print 'Update'


                    UPDATE [Final_Table]
                    SET [FULLNAME] = T.FULLNAME
                    ,[FATHERNAME] = T.FATHERNAME
                    ,[MOTHERNAME] = T.MOTHERNAME
                    ,[SPOUSENAME] = T.SPOUSENAME

                    from TMP_Source T
                    WHERE Final_Table.IKEy = T.IKEy 
                        and [Final_Table].[RCRD_CRN_DATE] < T.RCRD_CRN_DATE
                    --Print 'Update'
                end
                               else
                begin

                    INSERT INTO [Final_Table]
                    ([IKEy],[FTIN],[FULLNAME],[FATHERNAME],[MOTHERNAME],[SPOUSENAME]
                    )
                    Select IKEy,FTIN,FULLNAME,FATHERNAME,MOTHERNAME,SPOUSENAME
                    from TMP_Source 

                end  

The problem comes when I my T table has entries like -

   IKey RCRD_CRN_DATE ...
   123 10-11-2013-12.20.30
   123 10-11-2013-12.20.35
   345 10-11-2013-01.10.10

All three are inserted in the F table. Please help.

Remove all but the latest row as a first step (well, in a CTE ) using ROW_NUMBER() before attempting to perform the insert:

;WITH UniqueRows AS (
    SELECT IKey,RCRD_CRN_DATE,FULL_NAME,FATHER_NAME,MOTHER_NAME,SPOUSENAME,FTIN,
        ROW_NUMBER() OVER (PARTITION BY IKey ORDER BY RCRD_CRN_DATE desc) as rn
    FROM TMP_Source
)
MERGE INTO Final_Table t
USING (SELECT * FROM UniqueRows WHERE rn = 1) s
ON t.IKey = s.IKey
WHEN MATCHED THEN UPDATE
      SET [FULLNAME] = s.FULLNAME
         ,[FATHERNAME] = s.FATHERNAME
         ,[MOTHERNAME] = s.MOTHERNAME
         ,[SPOUSENAME] = s.SPOUSENAME
WHEN NOT MATCHED THEN INSERT
    ([IKEy],[FTIN],[FULLNAME],[FATHERNAME],[MOTHERNAME],[SPOUSENAME]) VALUES
    (s.IKEy,s.FTIN,s.FULLNAME,s.FATHERNAME,s.MOTHERNAME,s.SPOUSENAME);

(I may not have all the columns entirely correct, they seem to keep switching around in your question)

(As you may have noticed, I've also switched to using MERGE since it allows us to express everything as a single declarative statement rather than writing procedural code)

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