2013-06-28 99 views
0

我有兩個表 - > Order和OrderLine。訂單包含標題信息,是一對多關係的一面。 OrderLine包含組成訂單的行,並且是許多方面。假設我有3個訂單,每個訂單都有自己的ID,但每個訂單行的數據都是相同的,我認爲這是重複的,但前提是組中的所有記錄都是相同的。刪除重複分組數據的最佳方法 - SQL Server 2008

我已經嘗試過使用CheckSum_Agg來做這件事,但它會產生大量的誤報,導致記錄被刪除,並非完全重複。

試圖避免一個討厭,費力的嵌套遊標。

任何想法?

帖子編輯:的 --An例如假陽性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 

回答

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相匹配以查看它們是否匹配。如果他們都匹配,那麼他們是相互重複的。

這可能是一個非常昂貴的操作。我會推薦一個包含完整外部連接標準中所有列的索引來加速這個過程。

+0

感謝您的回覆。其實我已經嘗試過了,它不起作用。 這裏有一個場景的簡化的例子在那裏給誤報: 訂單行表包括這兩行 一階有兩個記錄: 訂單類型ID:1,產品編號:5 訂單類型ID:2,產品編號:6 二階有兩個記錄: 訂單類型ID:1,產品編號:6 訂單類型ID:2,產品編號:5 CHECKSUM_AGG說,這些是相同的,他們都沒有。 – Jimbo

+0

創建表#OrderLine(OrderId Int,ProductTypeId Int,ProductId Int);
插入進#OrderLine(的OrderId,ProductTypeId,產品編號)
值(1,1,5-),(1,2,6),(2,1,6),(2,2,5)

選擇CHECKSUM_AGG(ProductTypeId),CHECKSUM_AGG(產品編號)
從#OrderLine
集團通過的OrderId

刪除表#OrderLine
Jimbo

+0

很抱歉的格式。似乎不適合我。 – Jimbo

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 
相關問題