Как удалить строки в операторе слияния на конкретную дату, когда цель не соответствует источнику - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть оператор слияния, который выполняется каждый день, так как новые данные выгружаются в мою таблицу каждый день, вот пример моего кода:

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;

однако, который удаляет всю мою таблицу, яЖелая удалить только те строки, которые были добавлены сегодня, не следует прикасаться к любым предыдущим строкам.

Вот изображение того, как выглядят исходная и целевая таблицы:

Источник /Целевая таблица

У меня есть столбец с надписью 'saledate', в котором содержится дата сбрасываемых данных, и у меня есть уникальный столбец с надписью 'code', который я использовал для объединения для обнаружения дубликатов.

Интересно, есть ли a, если нет совпадений с источником для saledate = сегодня, затем удалить или что-то еще?

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Вы можете установить AND <clause_search_condition> после WHEN NOT MATCHED BY SOURCE.Указывает действительное условие поиска, а затем указывает, что строки, соответствующие строкам в target_table, удаляются.

Например, удалите строки, где source.saledate = today.

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;

Ваш проверенный форматэто "дд / мм / гг", поэтому нам нужно преобразовать формат даты по умолчанию.

Надеюсь, это поможет.

0 голосов
/ 04 апреля 2019

Оператор MERGE позволяет использовать только столбцы и столбцы цели в области условий сравнения в предложении «WHEN NOT MATCHED BY SOURCE».

Например, если вы хотите отфильтровать по датам в целевой таблице, тогда MERGE подходит для вашего случая, но если вы хотите отфильтровать по датам исходной таблицы, тогда это не подходит для MERGE

Вот полный пример с использованием простой таблицы

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
...