我有两张桌子 - >订单和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
答案 0 :(得分: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相匹配,以查看它们是否匹配。如果它们都匹配,那么它们就是彼此的重复。
这可能是一项非常昂贵的操作。我建议一个索引,它包含完整外连接critera中的所有列,以加快速度。
答案 1 :(得分: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