2013-10-10 63 views
0

您好我有一個下表說價SQL在3行顯示有重複值的行

CostID ItemID Level EffectiveFrom EffectiveTo    
6274751 12345 1  12/02/2013 NULL 
6274751 12345 1  13/02/2013 NULL 
6274751 12345 2  12/02/2013 NULL 
6254784 12345 1  12/02/2013 NULL 
6254784 12345 1  13/02/2013 NULL 
6244784 12345 9  12/02/2013 NULL 

我希望能夠編寫一個查詢通過比較3列「CostID'找到重複的行項目ID」和‘級別’,並顯示是重複的只有

預期輸出部分1

CostID ItemID Level EffectiveFrom EffectiveTo    
6274751 12345 1  12/02/2013 NULL 
6274751 12345 1  13/02/2013 NULL 
6254784 12345 1  12/02/2013 NULL 
6254784 12345 1  13/02/2013 NULL 

一旦我得到上述結果的人,我想從最後的更新生效至表重複的行

的部分預期輸出2

CostID ItemID Level EffectiveFrom EffectiveTo    
6274751 12345 1  12/02/2013 13/02/2013 
6274751 12345 1  13/02/2013 NULL 
6254784 12345 1  12/02/2013 13/02/2013 
6254784 12345 1  13/02/2013 NULL 

我嘗試這樣做:

{ 
SELECT * 
FROM price 
WHERE ItemID IN 
    ( SELECT ItemID 
      FROM price 
      GROUP BY ItemId   HAVING COUNT(distinct level) > 1 
    ) 
ORDER BY CostID } 

用於查詢的第一部分,但不能得到我想要的結果,任何幫助將是非常感激。

感謝

+0

你使用的是什麼sql? –

+0

SQL Server 2005,感謝您對我進行格式化 – user2865216

+0

有這麼多你想確定。請具體說明。請提供您的預期輸出。 –

回答

1

這會給你重複的行:

select distinct p.* 
from price p 
join price q 
    on p.CostID = q.CostID 
    and p.ItemID = q.ItemID 
    and p.Level = q.Level 
    and p.EffectiveFrom != q.EffectiveFrom 

條件p.EffectiveFrom != q.EffectiveFrom是重要的,因爲它停止加入到自己的所有行。通常情況下,您只需比較不平等的ID列,但您的表似乎沒有。


要與合適的結束日期更新較舊的行:

update p set 
p.EffectiveTo = dateadd(day, -1, q.EffectiveFrom) 
from price p 
join price q 
    on p.CostID = q.CostID 
    and p.ItemID = q.ItemID 
    and p.Level = q.Level 
    and p.EffectiveFrom < q.EffectiveFrom 

該查詢的唯一真正的區別被改變的不等式爲小於,從而選擇用於更新只有那些行的是是較早的那些。

請注意,我已從日期減去1天,因此沒有重疊。

+0

使用這個查詢,我得到了太多的結果,但如果我的表上有41,000條記錄,運行查詢後我得到100,000條記錄。我只想看到大約1000條重複記錄,所以我可以手動執行第2部分。就像在我的例子中,我有6條記錄,在運行查詢後,我希望看到4個重複記錄。謝謝 – user2865216

+0

你有幾個(多於兩個)具有相同密鑰數據的行嗎? – Bohemian

+0

當我運行第二個查詢時,它說表格的「價格」不明確 – user2865216

0

這一個有點長...但你可以做一些改進。

;WITH cte AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY CostID, ItemID, Level ORDER BY CostID, EffectiveFrom) AS RNUM, 
     CostID, 
     ItemID, 
     Level, 
     EffectiveFrom, 
     EffectiveTo 
    FROM @Price 
), 
cteDup AS 
(
    SELECT DISTINCT CostID, ItemID, Level FROM cte WHERE RNUM > 1 
) 
SELECT tt.* FROM @Price tt 
INNER JOIN cteDup cc ON tt.CostID = cc.CostID AND tt.ItemID = cc.ItemID AND tt.Level = cc.Level 

UPDATE:這將使直接更新,不知道這是你想要什麼壽。

;WITH cte AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY CostID, ItemID, Level ORDER BY CostID, EffectiveFrom) AS RNUM, 
     CostID, 
     ItemID, 
     Level, 
     EffectiveFrom, 
     EffectiveTo 
    FROM @Price 
) 
UPDATE c1 SET 
    EffectiveTo = c2.EffectiveFrom 
FROM cte c1 
INNER JOIN cte c2 ON c1.CostID = c2.CostID AND c1.ItemID = c2.ItemID AND c1.Level = c2.Level AND c1.RNUM + 1 = c2.RNUM 
+0

這給了我完美的結果,但是一旦結果顯示出來就無法更新。是否有更新查詢來實現第2部分,而無需執行第1部分? – user2865216