0

我有两个表-> 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
4

2 回答 2

1

我认为 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 匹配,以查看它们是否匹配。如果它们都匹配,那么它们就是彼此的重复。

这可能是一个非常昂贵的操作。我会推荐一个包含完整外部连接标准中的所有列的索引,以加快速度。

于 2013-06-29T15:22:59.463 回答
0

如果您允许在您的表中使用欺骗,我建议创建一个代理键以便轻松删除。最好不要一开始就允许它们,有一个独特的约束。但试试这个来清理。

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
于 2013-07-02T23:41:07.850 回答