简体   繁体   中英

How To Update Multiple Conditions Using MERGE Statements

I have to compare source and Target data and MERGE them accordingly. But I have multiple conditions. Below is my first set of source data

Source-Table1
ID       StartDate      EndDate     Designation
1        2018-01-01     2199-12-31  Associate Engineer
2        2018-02-01     2199-12-31  Software Engineer


Target-Table2
ID       StartDate      EndDate     Designation
1        2018-01-01     2199-12-31  Associate Engineer
2        2018-02-01     2199-12-31  Software Engineer


Create table Table1(
  Id int,
  StartDate datetime,
  EndDate   Datetime,
  Designation nvarchar(100)
  )

  Create table Table2(
  Id int,
  StartDate datetime,
  EndDate   Datetime,
  Designation nvarchar(100)
  )
--insert values
  insert into Table1 values(1,'2018-01-01','2199-12-31','Associate Engineer')
  insert into Table1 values(2,'2018-02-01','2199-12-31','Software Engineer')

  --Use Merge to Update/Insert values
MERGE Table2 t
  USING Table1 s
  on t.id=s.id
  WHEN MATCHED THEN 
  update SET
  t.id=s.id,
  t.StartDate=s.StartDate,
  t.EndDate=s.EndDate,
  t.Designation=s.Designation

  WHEN NOT MATCHED BY TARGET THEN
  INSERT(
  ID,
  StartDate,
  ENDDate,
  Designation
  )
  VALUES
  (s.ID,
  s.StartDate,
  s.EndDate,
  s.Designation)
  ;

Now, this code doesn't work if I have to update multiple conditions. For Example,if My source data has below values,then each ID cannot have overlap values. When there is new record for each ID, I have to check on StartDate, If start Date is < enddate then, update my old endDate to last day of the previous month and insert the new record else if ID and StartDate match, then update all records. If ID and StartDate does not mach then Insert.

Source-Table1
ID       StartDate      EndDate     Designation
1        2018-01-01     2199-12-31  Associate Engineer
1        2018-02-01     2199-12-31  Software Engineer
2        2018-02-01     2199-12-31  Software Engineer
2        2018-03-01     2199-12-31  Senior Software Engineer

Now I want my Target Table to have

ID       StartDate      EndDate     Designation
1        2018-01-01     2018-01-31  Associate Engineer
1        2018-02-01     2199-12-31  Software Engineer
2        2018-02-01     2018-02-28  Software Engineer
2        2018-03-01     2199-12-31  Senior Software Engineer

I am not able to do this Using MERGE statements.Can anyone of you help me to get this result?

If I understand your question correctly then you want to merge your source table with your target table. However, if a user's role has changed, example Associate Engineer to Software Engineer then you want to update the original record's EndDate to the last day of the month just before the new records start date. If my understanding is correct then you should be able to achieve this as follow:

;MERGE  [Table2] [T]
USING   (
            SELECT       [T1].[Id]
                        ,[T1].[StartDate]
                        ,CAST(LEAD(EOMONTH(DATEADD(DAY, -1, [T1].[StartDate])), 1, [T1].[EndDate]) OVER (PARTITION BY [T1].[Id] ORDER BY [T1].[StartDate]) AS DATETIME) AS [EndDate]
                        ,[T1].[Designation]
            FROM        [dbo].[Table1] [T1]
        ) [S]
ON ([T].[Id] = [S].[Id] AND [T].[StartDate] = [S].[StartDate])
WHEN MATCHED THEN 
    UPDATE 
            SET [T].[EndDate] = [S].[EndDate],
                [T].[Designation] = [S].[Designation]
WHEN NOT MATCHED BY TARGET THEN
    INSERT
    (
      [Id],
      [StartDate],
      [EndDate],
      [Designation]
    )
    VALUES
    (
        [S].ID,
        [S].StartDate,
        [S].EndDate,
        [S].Designation
    );

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