【问题标题】:SQL - Merge / Update & Delete from existing rowsSQL - 从现有行合并/更新和删除
【发布时间】:2018-06-26 21:32:37
【问题描述】:

给定下表:

A    B    C    D    E
a1   b1   NULL NULL e1 
NULL NULL c1   d1   NULL
a1   b1   c1   NULL NULL

我想运行一个查询,只要至少有一个列具有相等的值(NULL = NULL 除外),就会合并/更新和删除现有行以生成下表:

A    B    C    D    E
a1   b1   c1   d1   e1

请注意,任何列中都没有唯一 ID,因为任何列都可能有 NULL 值。

您能帮忙吗?

编辑:

如果任何列不共享相同的值,我会将它们作为单独的记录;这不会影响任何其他记录。

例如,如果第 3 行是:

A    B    C    D    E
a1   b1   c1   NULL e2

那么所需的输出将是:

A    B    C    D    E
a1   b1   NULL NULL e1 
a1   b1   c1   d1   e2

因为第 1 行已经有一个 e1 e2 (所以留作单独的记录);并且第 2 行和第 3 行被合并,因为它们共享 c1 作为一个公共 C 值并且也没有任何具有不同值的列(NULLS 除外)。

另一个例子:

如果有额外的行,第 4 行(与原始表格):

A    B    C    D    E
NULL NULL c1   d2   NULL

那么所需的输出将是:

A    B    C    D    E
a1   b1   c1   d1   e1
a1   b1   c1   d2   e1

【问题讨论】:

  • 您应该展示一个更好的数据示例,该示例汇总为多行。
  • 另外,如果样本数据中的第 3 行包含 E 值 e2,您将如何处理?还是存在 C 值为 c1 且 D 值为 d2 的附加行的情况?

标签: sql sql-server


【解决方案1】:

这并不是一个真正的完整答案,而是一个可以帮助其他人理解问题并希望帮助他们朝着正确的方向提供完整答案的答案:

据我了解,您描述的场景的根本问题是我们需要像 TRANSACTION(但可能不是 TRANSACTION)这样的东西,它可以让我们以某种方式完成以下步骤。

第 1 步。

在下表中,取第一行并将其与所有其他行进行比较。

A    B    C    D    E
a1   b1   NULL NULL e1 
NULL NULL c1   d1   NULL
a1   b1   c1   NULL NULL

对于第一行,我们在 [A] 列中找到与第三行匹配的内容,然后更新 [B]、[C]、[D] 和 [E] 列,然后删除第三行 -给我们下表:

A    B    C    D    E
a1   b1   c1   NULL e1 
NULL NULL c1   d1   NULL

第 2 步

我们查看列 [B] 并没有找到匹配项。

第 3 步

我们查看列 [C] 并找到匹配项,因此我们更新当前行(第 1 行)。我们忽略/不合并NULLs 所以我们得到下表

A    B    C    D    E
a1   b1   c1   d1   e1

这个问题是MERGE 操作不像描述的那样工作。我的意思是一旦一行是MERGED,我们就进入下一行。

这是一个相当复杂的过程,所以我个人不知道如何解决它,只是想以更“开发人员友好”的方式帮助解释问题。

我希望答案看起来像这样(我认为您实际上不能在 ON 子句中使用 isnull):

MERGE Table2 AS target
USING Table1 as source
ON (isnull(target.[A], -1) = isnull(source.[A], -2) OR isnull(target.[B], -1) = isnull(source.[B], -2), etc.... )
WHEN MATCHED 
THEN UPDATE
    SET target.[A] = source.[A]

等等……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    相关资源
    最近更新 更多