繁体   English   中英

删除重复的分组数据的最佳方法-SQL Server 2008

[英]Best way to remove duplicated grouped data - SQL Server 2008

我有两个表-> Order和OrderLine。 订单包含标头信息,并且是一对多关系的一面。 OrderLine包含组成订单的行,并且有很多方面。

可以说我有3个订单,每个订单都有自己的ID,但是每个订单行的数据都是相同的,我认为这是重复的,但前提是该组中的所有记录都相同。

我已经尝试过使用CheckSum_Agg,但是它会产生大量的误报,导致删除的记录不是完全重复的。

试图避免讨厌的,费力的嵌套游标。

有任何想法吗?

发布编辑:-CheckSum_Agg返回假阳性的示例...

Create Table #OrderLine(OrderId Int,ProductTypeId Int,ProductId Int);
Insert Into #OrderLine(OrderId,ProductTypeId,ProductId)
Values(1,1,5),(1,2,6),(2,1,6),(2,2,5)

Select CHECKSUM_Agg(ProductTypeId),CHECKSUM_Agg(ProductId)
From #OrderLine
Group By OrderId

Drop Table #OrderLine

我认为CheckSum_Agg是一个好的开始。 您可能只在一列上执行CheckSum_Agg。 如果您对感兴趣的每一列都执行一个CheckSum_Agg,则可以找到所有重复项。 您可能不希望应用CheckSum_Agg的唯一列是OrderLine.id和OrderLine.OrderId。

这是一个查询,将查询两个订单是否相同:

with o as (
  select distinct orderid from orderline)
, ol as (select * from orderline)
select o1.orderid as o1, o2.orderid as o2
from o o1, o o2 
where o1.orderid <> o2.orderid and
0= (select count(*) 
          from (select * from ol where ol.orderid = o1.orderid) ol1 
          full outer join 
            (select * from ol where ol.orderid = o2.orderid) ol2 
            on ol1.producttypeid = ol2.producttypeid
            and ol1.productid = ol2.productid
          where (ol2.orderid is null or ol1.orderid is null))

这是一个正在显示它的小提琴: http : //sqlfiddle.com/#!3/359e5/8

这里的想法是获取所有订单对(o1,o2),并将o1的订单线ol1与o2的订单线ol2匹配,以查看它们是否匹配。 如果它们都匹配,则它们是彼此重复的。

这可能是非常昂贵的操作。 我建议使用一个索引,该索引在完整的外部联接critera中具有所有列,以加快此速度。

如果您允许在表中使用重复项,建议您创建一个代理密钥以方便删除。 最好不要在具有唯一约束的情况下首先使用它们。 但是,请尝试清理。

Create Table #OrderLine(Pk INT IDENTITY PRIMARY KEY, OrderId Int,ProductTypeId Int,ProductId Int);
Insert Into #OrderLine(OrderId,ProductTypeId,ProductId)
Values(1,1,5),(1,2,6),(2,1,6),(2,2,5),(1,1,5), (1,1,5)

--check
SELECT * FROM #OrderLine

--any dupes?
SELECT * FROM #OrderLine WHERE Pk NOT IN (
    Select Min(Pk)
    From #OrderLine
    Group By OrderId,ProductTypeId,ProductId
)

--delete the dupes
DELETE FROM #OrderLine WHERE Pk NOT IN (
    Select Min(Pk)
    From #OrderLine
    Group By OrderId,ProductTypeId,ProductId
)

--check
SELECT * FROM #OrderLine

Drop Table #OrderLine

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM