【问题标题】:How to Update duplicated Rows into One Row如何将重复的行更新为一行
【发布时间】:2020-04-23 10:42:30
【问题描述】:

我需要合并相同的条目并逐行汇总数量。例如:

glass type  height   width    quantity
---------------------------------------
4DC          1500     600        1
4DC          1500     600        2
4DC          1200     500        5
4DC          1200     500        2
3DC          1500     600        2

将是:

glass type   height   width   quantity
---------------------------------------
4DC           1500     600      3
4DC           1200     500      7
3DC           1500     600      2

但我不想要任何选择查询,我需要更新表并删除重复行并使用总和数量更新其中之一。

我该怎么做?

【问题讨论】:

  • 您至少需要在此处 SELECT 将数据移动到临时对象或 CTE 中。此外,您不能在单个查询中 DELETE UPDATE。您可以使用MERGE,但我建议单独声明会更​​好。

标签: sql sql-server duplicates rows


【解决方案1】:

我的建议是换表:

select glasstype, height, width, sum(quantity) as quantity
into temp_t
from t
group by glasstype, height, width;

truncate table t;  -- backup first!

insert into temp_t (glasstype, height, width, quantity)
    select glasstype, height, width, quantity
    from temp_t;

drop table temp_t;

或者,您可以分两步执行此操作:

with toupdate as (
      select t.*, sum(quantity) over (partition by glasstype, height, width) as new_quantity
      from t
     )
update toupdate
    set quantity = new_quantity;

with todelete as (
      select t.*,
             row_number() over (partition by glasstype, height, width order by glasstype) as seqnum
      from t
     )
delete from todelete
    where seqnum > 1;

【讨论】:

  • 谢谢,我用了这个策略,效果很好。但我有一个问题。我应该在每次合并过程后删除这个临时表吗?
  • 您可能应该创建一个变量,如 declare @tempTable table (glasstype varchar(10) ..... 因此,只要查询完成,它就会被释放
  • @TuğhanAvcı 。 . .这不使用临时表,所以你应该手动删除它。我也不推荐表变量——如果你截断表后数据库崩溃,那么你不想丢失数据。
【解决方案2】:

我会做与 Gordon 类似的事情,但是,我会重命名这些对象:

SELECT GlassType,
       Height,
       Width,
       SUM(Quantity)
INTO dbo.NewTable
FROM dbo.YourTable
GROUP BY GlassType,
         Height,
         Width;
GO
EXEC sp_rename N'dbo.YourTable',N'OldTable';
GO
EXEC sp_rename N'dbo.NewTable',N'YourTable';
GO

这意味着您仍然拥有旧表的副本,如果您有任何外键,您将无法TRUNCATE。但是,您必须在新的 YourTable 上重新创建任何现有约束和索引

然后我会在你的桌子上创建一个唯一约束,这样你以后就不会出现重复。

ALTER TABLE dbo.YourTable ADD CONSTRAINT UC_TypeHeightWidth UNIQUE (GlassType,Height,Width);

【讨论】:

  • 谢谢,但我无法更改表名,因为它已满是数据
  • 当 Gordon 推荐 TRUNCATE 时,不确定您所说的 @TuğhanAvcı 是什么意思; 删除您的所有数据,但仍然。
猜你喜欢
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多