I have two tables - source and destination, which are similar. They look like this:
CREATE TABLE [dbo].[srcTable](
[Id] [INT] NULL,
[Value] [INT] NULL,
[QueryDate] [DATE] NULL
)
CREATE TABLE [dbo].[destTable](
[Id] [INT] NULL,
[Value] [INT] NULL,
[QueryDate] [DATE] NULL
)
I have the following data in these tables:
TRUNCATE TABLE [dbo].[srcTable]
INSERT INTO [dbo].[srcTable]
(
[Id],
[Value],
[QueryDate]
)
SELECT 2, 3, '2023-01-03'
UNION ALL
SELECT 2, 3, '2023-03-03'
UNION ALL
SELECT 3, 4, '2023-03-02'
UNION ALL
SELECT 5, 6, '2023-03-04'
UNION ALL
SELECT 3, 4, '2023-03-17'
TRUNCATE TABLE [dbo].[destTable]
INSERT INTO [dbo].[destTable]
(
[Id],
[Value],
[QueryDate]
)
SELECT 1, 2, '2023-03-03'
UNION ALL
SELECT 1, 2, '2023-03-10'
I want to always have the most recent QueryDate set in the [dbo].[destTable].
If there is a dataset in the [dbo].[srcTable] which matches the YearWeek of a dataset in the [dbo].[destTable], and the QueryDate of the source is equal or greater than the QueryDate of the destination, then the dataset for this YearWeek in the [dbo].[destTable] should be deleted and a new dataset should be inserted in the [dbo].[destTable] from the source table.
If there is no data in [dbo].[destTable] for a specific YearWeek, then the data is inserted in [dbo].[destTable] from the source.
The requirement is to group the data by YEAR-WEEK and also to compare the QueryDate column per week.
So, after running my query based on the data above, the [dbo].[destTable] will look like this:
SELECT 2, 3, '2023-01-03'
UNION ALL
SELECT 5, 6, '2023-03-04'
UNION ALL
SELECT 1, 2, '2023-03-10'
UNION ALL
SELECT 3, 4, '2023-03-17'
I am trying to use a MERGE statement, but I am not sure how to delete the destination and insert at the same time when the data is matched. I tried this:
MERGE [dbo].[destTable] AS T
USING (SELECT * FROM [dbo].[srcTable] ) AS S
ON CAST(YEAR(T.[QueryDate]) AS VARCHAR(4)) +'-'
+ CAST(DATEPART(WEEK, T.[QueryDate]) AS VARCHAR(2)) = CAST(YEAR(S.[QueryDate]) AS VARCHAR(4)) +'-'
+ CAST(DATEPART(WEEK, S.[QueryDate]) AS VARCHAR(2))
WHEN MATCHED AND S.[QueryDate] => T.[QueryDate] THEN
DELETE
-- delete from target and insert again
WHEN NOT MATCHED BY TARGET THEN
INSERT ([Id],
[Value],
[QueryDate])
VALUES (S.[Id],
S.[Value],
S.[QueryDate])
;
Another idea is to spell out the logic to multiple deletes and inserts, nested in a loop for each distinct Year-Week in the source, but this seems long and clumsy. Is there a better way to make the MERGE statement work?