代码之家  ›  专栏  ›  技术社区  ›  chris_techno25

如何在没有主键的情况下合并UPDATE中的2行或多行并求和一列?

  •  0
  • chris_techno25  · 技术社区  · 2 年前

    我在SQL Server中有一个表,如下所示:

    C交易 Q数量 CItemCode CUOM
    001 2. 0011 包装
    001 5. 0011 包装
    001 1. 0011 包装
    002 3. 0011 包装
    002 3. 0011 包装

    基本上,此表包含相应的项目详细信息 CTransaction 。我想合并和更新具有相同 C交易 和 CItemCode 同时总结他们 CQuantity .

    更新后,结果会变成下表所示的样子。。。

    C交易 Q数量 CItemCode CUOM
    001 8. 0011 包装
    002 6. 0011 包装

    我在中发现了一个类似的问题 here ,但是该示例包括主键。我的表没有主键,我不知道该怎么做。这可能吗?请帮帮我。

    如果我只是想 SELECT 行如下所示:

    SELECT 
        CTransaction, SUM(CQuantity), CItemCode, CUOM 
    FROM 
        Table 
    GROUP BY 
        CTransaction, CItemCode, CUOM
    

    但我不想这样。我想更新表以永久删除重复项。

    非常感谢。

    2 回复  |  直到 2 年前
        1
  •  1
  •   Martin Smith    2 年前

    每个表都应该有一个主键。在这种情况下,主键应该是 CTransaction, CItemCode, CUOM 并且您应该修复这个过程来打乱这一正在进行的操作,而不是添加新的重复行。

    可以使用 MERGE 尽管如此。一种方法如下(为每组更新任意一个,并删除其余部分)。

    WITH Tgt AS
    (
    SELECT *, 
            SumCQuantity = SUM(CQuantity) OVER (PARTITION BY CTransaction, CItemCode, CUOM ),
            rn = ROW_NUMBER() OVER (PARTITION BY CTransaction, CItemCode, CUOM  ORDER BY CTransaction) 
    FROM YourTable
    ) 
    Merge Tgt with (HOLDLOCK)
    USING (VALUES(1)) src(rn) ON Tgt.rn = 1
    WHEN MATCHED AND CQuantity IS DISTINCT FROM SumCQuantity THEN 
        UPDATE SET CQuantity = SumCQuantity 
    WHEN NOT MATCHED BY SOURCE THEN 
        DELETE;
    

    Fiddle

        2
  •  1
  •   Tim Biegeleisen    2 年前

    考虑到您已经说过可能需要定期进行此汇总,使用您已经创建的聚合查询在源表的顶部创建一个视图可能是最有意义的:

    CREATE VIEW yourView AS
    SELECT CTransaction, CItemCode, CUOM, SUM(CQuantity)
    FROM yourTable
    GROUP BY CTransaction, CItemCode, CUOM;
    

    那就用 SELECT * FROM yourView 只要您需要访问这些数据。