来自临时表的SQL合并导致重复行
我有一个SQL Server存储过程,它在一个临时表和几个目标表之间移动数据。在一个表中,我试图更新两列,它们标识最初标记的时间和最后标记的时间。这些表的定义如下来自临时表的SQL合并导致重复行,sql,sql-server,merge,Sql,Sql Server,Merge,我有一个SQL Server存储过程,它在一个临时表和几个目标表之间移动数据。在一个表中,我试图更新两列,它们标识最初标记的时间和最后标记的时间。这些表的定义如下 MyStaging表格: STAGING_ROW_ID* FILE_DATETIME IMPORT_ID UPDATE_ID COMPUTER_IP 1 '2020-08-27 11:44:47.000' 1 10
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
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
MyTable
表格:
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
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\u DATETIME
列导致一些重复项。由于UPDATE\u ID
和COMPUTER\u IP
是MyTable
中的一个复合键,它将有多个FILE\u DATETIME
条目,这是可以理解的
我的问题是,如何更改合并以获取这些日期,同时仍然只获取适当的列?在update语句中,我只需要更新
LAST\u DATE\u-FLAGGED
列。在插入中,我只需要将最新日期同时作为第一个和最后一个日期。如果我理解正确,您可以将using子句更改为useMAX
以获取最新的日期数据
MERGE INTO dbo.MyTable mt
USING (SELECT UPDATE_ID, COMPUTER_IP, MAX(FILE_DATETIME) AS FILE_DATETIME, COUNT(*) AS TOTAL_NUMBER
FROM dbo.MyStaging
WHERE "IMPORT_ID" = @importID
GROUP BY UPDATE_ID, COMPUTER_IP) 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);
要求不明确。您想更新已标识的
最后日期
,但您正在更新已标记的最后日期
。如果是多行,更新时应考虑哪一行?count(*)基于什么?抱歉,列名以“标记”结尾。我已经编辑过了。正如我所问的,如果有多个值要更新到LAST\u DATE\u标记的和count(*)对于复合密钥或包含日期?标记的LAST_date_应该是该特定复合密钥的最新日期。请阅读-可能您的批次还有更多,但如果您没有使用正确的锁定/隔离,则肯定存在问题。