【发布时间】:2020-09-02 16:51:47
【问题描述】:
我有一个 SQL Server 存储过程,它在一个临时表和几个目标表之间移动数据。有一个表,我正在尝试更新两列,这些列标识最初标记某事物的时间和最后一次标记的时间。表是这样定义的
MyStaging表:
STAGING_ROW_ID* FILE_DATETIME IMPORT_ID UPDATE_ID COMPUTER_IP
1 '2020-08-27 11:44:47.000' 1 100-1 192.168.100.1
2 '2020-08-31 12:15:48.000' 1 100-1 192.168.100.1
3 '2020-08-31 12:30:10.000' 1 100-2 192.168.100.2
MyTable表:
UPDATE_ID* COMPUTER_IP* FIRST_DATE_FLAGGED LAST_DATE_FLAGGED TOTAL_NUMBER
100-1 192.168.100.1 2020-08-27 11:44:47.000 2020-08-31 12:15:48.000 2
100-2 192.168.100.2 2020-08-31 12:30:10.000 2020-08-31 12:30:10.000 1
*星号表示主键
在合并期间,我正在尝试这样做:
MERGE INTO dbo.MyTable mt
USING (SELECT UPDATE_ID, COMPUTER_IP, FILE_DATETIME, COUNT(*) AS TOTAL_NUMBER
FROM dbo.MyStaging
WHERE "IMPORT_ID" = @importID
GROUP BY UPDATE_ID, COMPUTER_IP, FILE_DATETIME) ms ON mt.UPDATE_ID = ms.UPDATE_ID
AND mt.COMPUTER_IP = ms.COMPUTER_IP
WHEN MATCHED THEN
UPDATE
SET
mt.TOTAL_NUMBER = mt.TOTAL_NUMBER + ms.TOTAL_NUMBER,
mt.LAST_DATE_FLAGGED = CASE WHEN ms.FILE_DATETIME > mt.LAST_DATE_FLAGGED
THEN ms.FILE_DATETIME
ELSE mt.LAST_DATE_FLAGGED
END
WHEN NOT MATCHED THEN
INSERT (UPDATE_ID, COMPUTER_IP, FIRST_DATE_FLAGGED, LAST_DATE_FLAGGED, TOTAL_NUMBER)
VALUES (ms.UPDATE_ID, ms.COMPUTER_IP, ms.FILE_DATETIME, ms.FILE_DATETIME, ms.TOTAL_NUMBER);
我知道这不是正确的方法。我收到一个错误,因为 FILE_DATETIME 列会导致一些重复。由于UPDATE_ID 和COMPUTER_IP 是MyTable 中的复合键,并且FILE_DATETIME 会有多个条目,这是可以理解的。
我的问题是如何更改我的合并以获取这些日期,同时仍然只获取适当的列?在更新语句中,我只需要更新LAST_DATE_FLAGGED 列。在插入中,我只需要将最晚日期同时作为第一个日期和最后一个日期。
【问题讨论】:
-
需求不明确。您想更新
LAST_DATE_IDENTIFIED,但您正在更新LAST_DATE_FLAGGED。如果有多个更新应该考虑哪一行?什么是 count(*) 基于? -
抱歉,列名以“FLAGGED”结尾。已编辑。
-
正如我所问的,如果有多个值要更新为
LAST_DATE_FLAGGED和 count(*) 作为复合键或包括日期? -
LAST_DATE_FLAGGED 应该是该特定复合键的最新日期。
-
请阅读MERGE with caution - 也许您的批次还有更多内容,但如果您没有使用正确的锁定/隔离,肯定会出现问题。
标签: sql sql-server merge