【问题标题】:T-SQL MERGE: Each GROUP BY expression must contain at least one column that is not an outer referenceT-SQL MERGE:每个 GROUP BY 表达式必须至少包含一个不是外部引用的列
【发布时间】:2018-09-04 11:49:56
【问题描述】:

在使用SELECT CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine), MAX(SOURCE.LastDate) GROUP BY CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine)SELECT CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine), MAX(TARGET.LastDate) GROUP BY CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine)

MERGE dbo.TargetTbl AS TARGET
USING dbo.SourceTbl AS SOURCE 
      ON (TARGET.OrderNo = SOURCE.OrderNo) 
WHEN MATCHED AND EXISTS (SELECT           CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine)
                                         ,MAX(SOURCE.LastDate)
                         GROUP BY         CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine)
                         INTERSECT SELECT CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine)
                                         ,MAX(TARGET.LastDate)
                         GROUP BY         CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine)
                        )
THEN UPDATE SET TARGET.IsBlocked = 1;

我得到这个错误:

每个 GROUP BY 表达式必须至少包含一列 外部参考。

我搜索并找到了一些解决方案,但它们都不适用于我的查询,或者至少我不知道如何。任何帮助将不胜感激。

编辑:我绝对可以在 SOURCE & TARGET 表中有两个相同的行,它会抛出这个错误:

MERGE 语句尝试更新或删除同一行 不止一次。当目标行匹配多个源时会发生这种情况 排。 MERGE 语句不能更新/删除目标的同一行 表多次。细化 ON 子句以确保目标行 最多匹配一个源行,或使用 GROUP BY 子句进行分组 源行。

通过添加 GROUP BY 它给了我上面提到的外部引用错误。

【问题讨论】:

    标签: sql-server tsql merge


    【解决方案1】:

    您不需要 INTERSECT,因为 Merge 已经在 Source 表和 Target 表之间比较了您的数据。试试下面的东西。

    MERGE dbo.TargetTbl AS TARGET
    USING 
    (
        SELECT  CONCAT(OrderNo, '_', OrderLine) AS OrderLineNo,
                MAX(LastDate) AS LastDate
        FROM dbo.SourceTbl
        GROUP BY CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine)
    ) AS SOURCE 
        ON SOURCE.OrderNo = TARGET.OrderNo 
        AND SOURCE.OrderLineNo = CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine)
        AND SOURCE.LastDate = TARGET.LastDate
    WHEN MATCHED THEN UPDATE 
            SET TARGET.IsBlocked = 1;
    

    【讨论】:

    • 我设法在没有 MAX 和 GROUP BY 的情况下做到了,但我需要做一些测试以验证它是否防错。如果您不使用 SELECT ... INTERSECT/EXCEPT SELECT,您的代码如何处理 NULL?我使用了本指南:sqlblog.com/blogs/paul_white/archive/2011/06/22/…
    • 抱歉,我对“代码句柄 NULL”有点困惑。我需要知道你想要达到什么目标?因为about脚本在目标表和源表之间进行了比较。如果满足任何 ON 条件,那么您似乎想要阻止订单。但似乎还有更多。比你想多了。
    • 我们可以向 MERGE 添加额外的语句。例如除了,如果记录在 SOURCE 表中但不在 TARGET 表中,那么您要插入记录吗?或者如果记录在 TARGET 表中但不在 SOURCE 表中,您是否希望在 TARGET 表中删除记录?
    • 我省略了 WHEN NOT MATCHED 部分,因为它不相关。我可以做一个基本的“当记录匹配时,如果有任何(或没有)更改,更新记录”,但为了正确处理空值,我使用了 INTERSECT,如下所示:stackoverflow.com/questions/4509722/… 到目前为止一切都很好。
    • 当我在两个 SELECT(INTERSECT 部分)中添加 MAX 和 GROUP BY 时,它抛出了外部引用错误。我找到了一种解决方法,希望不需要使用 MAX 和 GROUP BY 关键字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 2020-05-10
    • 1970-01-01
    相关资源
    最近更新 更多