【问题标题】:SQL Merge with inserting into the third table插入第三张表的 SQL 合并
【发布时间】:2012-03-12 23:07:06
【问题描述】:

我想创建一个合并,它将比较两个表并将不匹配的值插入另一个第三个表或表变量 像这样:

MERGE Assets AS target
USING (@id, @name)FROM Sales AS source (id, name) ON (target.id = SOURCE.id)
WHEN MATCHED THEN 
    UPDATE SET target.Status = @status, target.DateModified = SYSUTCDATETIME()
WHEN NOT MATCHED THEN 
    INSERT INTO @tableVar (id, name, status, dateModified)  
    VALUES (@id, @name, @status, SYSUTCDATETIME())

可以这样做还是有其他方法?

【问题讨论】:

    标签: sql-server tsql sql-merge


    【解决方案1】:

    你只是不能这样做。 MERGE 仅在两个表上运行 - 源和目标。

    根据您的要求,您需要例如使用 CTE(通用表表达式)查找不匹配的行 - 并将它们插入到第三个表中。

    类似:

    ;WITH NonMatchedData AS
    (
       -- adapt this as needed - just determine which rows match your criteria,
       -- and make sure to return all the columns necessary for the subsequent INSERT
       SELECT (columns)
       FROM dbo.SourceTable
       WHERE ID NOT IN (SELECT DISTINCT ID FROM dbo.TargetTable)
    )
    INSERT INTO dbo.ThirdTable(Col1, Col2, ....., ColN)
      SELECT Col1, Col2, ....., ColN
      FROM NonMatchedData
    

    【讨论】:

    • 在这种情况下是否有替代 NOT IN 的方法?类似于JOIN 的东西会重新调整所有失败到JOIN 的行?除了LEFT JOIN + IS NULL。另外,CTE真的有必要吗?他不能INSERT INTO ThirdTable FROM SELECT NonMatchedData吗?
    • @PeekaySwitch: 当然 - 但是你 ARE 做一个LEFT OUTER JOIN 并检查来自dbo.TargetTable 的列是NULL .... 我不'真的不知道还有什么其他选择......
    • 你知道什么能提供更好的性能吗?我希望LEFT OUTER JOIN 更有效,但也许它们靠得很近,我总是尽量避免使用NOT INWhere 中的大量数据(如ID)
    • @PeekaySwitch:标准答案:视情况而定! - 没有明确的答案。这取决于表的大小、行数、您拥有的索引......基本上,如果这种性能对您来说是一个问题/问题:尝试它们,测量它们,比较执行计划 - 看看哪个更适合您。在不知道您的数据和业务的情况下,我不能从这里这么说......
    • 哈哈,好!非常感谢您花时间回答我的一些问题!总的来说,我仍然在关注 CTE 和 T-SQL!能与懂 T-SQL 的人交流很有趣!
    【解决方案2】:

    你可以很容易地做到这一点......

    您可以将 MERGE 语句包装在 INSERT INTO FROM 中:
    http://technet.microsoft.com/en-us/library/bb510625.aspx#sectionToggle2

    -或-

    您可以直接在合并语句中执行此操作:

    快速示例:

    WHEN NOT MATCHED THEN
        DELETE
    OUTPUT Deleted.* INTO dbo.MyTable;
    

    这会将不匹配项插入到您现有的目标表中。您可以使用已更新、已插入、已删除的 v-tables 将数据定向到其他位置。

    【讨论】:

    • 这需要在MATCHEDNOT MATCHED BY SOURCE 子句中,但它确实可以解决问题。
    • 这是实际的答案,应该得到更多的支持。如此简单和美好。
    • 有人可以对“快速示例”进行注释,并详细说明其工作原理吗?例如,OUTPUT 是 DELETE 的一部分,还是 MERGE 的一部分?
    • @MichaelPotter 输出是合并的一部分。查看文档中的语法。您正在寻找 docs.microsoft.com/en-us/sql/t-sql/statements/…
    • 第一个版本的示例将很好,而不仅仅是一个链接,尤其是因为此链接会自动转到最新的 SQL Server 版本,而不是最初打算链接的那个 OP。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    相关资源
    最近更新 更多