【问题标题】:SQL - Merge trying to INSERT instead of UPDATE because of NULL columnsSQL - 由于 NULL 列,合并尝试插入而不是更新
【发布时间】:2016-11-24 06:57:30
【问题描述】:

大家好,祝大家有美好的一天。 我正在尝试在table2table1 两个表上执行以下序列。

MERGE INTO table2 WITH (HOLDLOCK) AS target
    USING
    (
      SELECT column1,
             MAX(AccessDate) AS AccessDate,
             SUM(AccessCount) AS AccessCount,
             column4,
             column5, 
             column6, 
             column7, 
             column8
      FROM  table1
      GROUP BY column1, column4, column5, column6, column7, column8
    ) AS source
    ON target.column1 = source.column1 AND
       target.column5 = source.column5 AND
       target.column6 = source.column6 AND
       target.column7 = source.column7 AND
       target.column8 = source.column8
    WHEN MATCHED THEN 
    UPDATE SET target.LastAccessDate = source.AccessDate,
       target.LastWeeklyAccessCount = source.AccessCount
    WHEN NOT MATCHED BY TARGET THEN
       INSERT (column1, LastAccessDate, LastWeeklyAccessCount, column4, column5, column6, column7, column8)
        VALUES (source.column1, source.AccessDate, source.AccessCount, source.column4, source.column5, source.column6, source.column7, source.column8);

使用table1 中的现有日期,它会做它应该做的事情。 如果我在满足 JOIN 条件的情况下在 table1 中插入另一条记录,它会尝试插入而不是 UPDATE,因为在比较两个表时出现 NULLNULL,这是因为我有 UNIQUE 约束:

无法在对象“dbo.table2”中插入重复键。

谁能帮我解决这个问题?

【问题讨论】:

  • 哪些字段可以是NULL
  • column5, column6, column8
  • 如果将nullnull 匹配,它会正常工作吗:((target.column5 = source.column5) OR (target.column5 IS NULL AND source.column5 IS NULL)) AND。同样对于其他可以为空的列...
  • @BogdanPuşcaşu 您可以使用 user1429080 评论解决您的问题
  • 确实,您的解决方案奏效了!非常感谢你帮助我。

标签: sql sql-server tsql sql-merge


【解决方案1】:

一种方法:

ON target.column1 = source.column1 AND
   ISNULL(NULLIF(target.column5, source.column5), 
            NULLIF(source.column5, target.column5)) IS NULL AND
   ISNULL(NULLIF(target.column6, source.column6), 
            NULLIF(source.column6, target.column6)) IS NULL AND
   target.column7 = source.column7 AND
   ISNULL(NULLIF(target.column8, source.column8), 
            NULLIF(source.column8, target.column8)) IS NULL

NULLIF 将返回 NULL 如果两个值相同,ISNULL 将选择第一个非空值(或 NULL 如果两个值都为空)所以如果 ISNULL 的结果是 @ 987654327@ 表示两个值相同(NULL 或相同值)。

【讨论】:

    【解决方案2】:

    www.made2mentor.com 对此进行了很好的讨论。他建议使用 EXCEPT,因为它比所有替代方案都更好地处理 NULL。片段:

    WHEN MATCHED AND EXISTS
        (SELECT Source.CustomerName, Source.Planet
         EXCEPT
         SELECT Target.CustomerName, Target.Planet)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 2019-09-21
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      相关资源
      最近更新 更多