来自临时表的SQL合并导致重复行

来自临时表的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

我有一个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
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子句更改为use
MAX
以获取最新的日期数据

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_应该是该特定复合密钥的最新日期。请阅读-可能您的批次还有更多,但如果您没有使用正确的锁定/隔离,则肯定存在问题。