如何删除目标与源不匹配的特定日期的合并语句中的行

How to delete rows in merge statement for specific date where target doesnt match source

我有一个每天运行的合并语句,因为每天都有新数据转储到我的 table 中,这是我的代码示例:

MERGE SQL_Backup as Target 
USING Temp as Source 
ON target.code = source.code 
WHEN MATCHED THEN update SET 
target.saledate = source.saledate, 
target.branchcode = source.branchcode 

WHEN NOT MATCHED BY TARGET 
THEN insert ( 
code, saledate
) 
values ( 
source.code, source.saledate 
)

    when not matched by source
      then delete;

然而,这会删除我的整个 table,我只想删除今天添加的行,不应触及任何以前的行。

这是源和目标 table 的图像:

Source/Target Table

我有一个标记为 'saledate' 的列,其中包含转储数据的日期,我有一个标记为 'code' 的唯一列,我将其用于合并以检测重复项。

想知道是否有一个 when 与 saledate = today 的来源不匹配然后删除或其他什么?

MERGE 语句只允许在 "WHEN NOT MATCHED BY SOURCE" 子句中使用目标的列和比较项范围内的列。

例如,如果您想按目标 table 中的日期进行过滤,则 MERGE 适合您的情况,但如果您想按源 table 中的日期进行过滤,则这不适用适合 MERGE

这是一个使用简单 table

的完整示例
DROP TABLE IF EXISTS S
DROP TABLE IF EXISTS T
GO
CREATE TABLE S(
    id int,
    DT DATE
)
DROP TABLE IF EXISTS T
GO
CREATE TABLE T(
    id int,
    DT DATE
)

INSERT T(id, DT) values (1,'2000-01-01'),(2,'2000-01-01'),(3,'2019-01-01')
INSERT S(id, DT) values (3,'2000-01-01'),(4,'2000-01-01'),(5,'2019-01-01')
GO

SELECT * FROM T
SELECT * FROM S
GO

-- the following query will raise an error
MERGE T as Target USING S as Source
    ON Target.id = Source.id

    WHEN MATCHED THEN 
        UPDATE SET Target.id = Source.id + 1000
    WHEN NOT MATCHED BY TARGET THEN 
        insert (id, DT) values (Source.id, Source.DT)
    -- Only target columns and columns in the clause scope are allowed in the 'WHEN NOT MATCHED BY SOURCE' clause of a MERGE statement.
    -- Using the bellow wil raise an error:
     WHEN NOT MATCHED BY SOURCE AND Source.DT > '2005-01-01' THEN DELETE;
GO

-- the following query will work well
MERGE T as Target USING S as Source
    ON Target.id = Source.id

    WHEN MATCHED THEN 
        UPDATE SET Target.id = Source.id + 1000
    WHEN NOT MATCHED BY TARGET THEN 
        insert (id, DT) values (Source.id, Source.DT)
    -- The bellow will work OK, since I use condition on the TARGET
    WHEN NOT MATCHED BY SOURCE AND TARGET.DT > '2005-01-01' THEN DELETE;
GO

SELECT * FROM T
SELECT * FROM S
GO

您可以在WHEN NOT MATCHED BY SOURCE之后设置AND <clause_search_condition>。 指定有效的搜索条件,然后指定删除与target_table中的行匹配的行。

例如,删除 source.saledate=今天的行。

MERGE SQL_Backup as Target 
USING Temp as Source 
ON target.code = source.code 
WHEN MATCHED THEN update SET 
target.saledate = source.saledate, 
target.branchcode = source.branchcode 

WHEN NOT MATCHED BY TARGET 
THEN insert ( 
code, saledate
) 
values ( 
source.code, source.saledate 
)

WHEN NOT MATCHED BY SOURCE AND  source.saledate = CONVERT(varchar(100), GETDATE(), 3)
THEN DELETE;

您的销售日期格式是"dd/mm/yy",所以我们需要转换默认的日期格式。

希望对您有所帮助。