2013-11-14 58 views
1

我有這個表在我的數據庫:刪除重複的行不是基於主鍵

tblAgencies 
---------------------- 
AgencyID (PK) 
VendorID 
RegionID 
Name 
Zip 

長話短說,我不小心抄我的整個表到自己 - 所以在我的表中的每一行都有一個副本。

但我的AgencyID字段是身份,並自動遞增,我需要根據所有其他字段找到重複項,因爲AgencyID是唯一的。

有誰知道我該怎麼做?

+1

如果您的PK是自動遞增的,您不能僅僅運行一個DELETE,其中AgencyID> [最後一個良好記錄]? – Jed

+0

使用row_number爲任何列做出重複,並刪除它= 2? – Andrew

回答

1

最簡單的解決方案,使用選擇不同的到一個臨時表,然後重新加載原始

+1

這隻有在沒有外鍵引用原始表時纔有效。 – Szymon

0

該查詢會給你重複提供的所有其他列的組合是唯一的:

select * from mytable t1 
where exists 
     (select * from mytable t2 
     where t1.VendorID = t2.VendorID 
     and t1.RegionID = t2.RegionID 
     and and t1.Name = t2.Name 
     and t1.Zip = t2.Zip 
     and t1.AgencyID > t2.AgencyID) 
0

這應該爲您提供所有具有重複值的行,除了最小的代理行號。

select * 
    from tblAgencies 
    where AgencyID not in (select min(AgencyID) 
          from tblAgencies 
          group by VendorID, RegionID, Name, Zip) 

編輯:添加SQLFiddle

3

這將保持最古老的AgencyID值,否則刪除任何重複。

;WITH x AS 
(
    SELECT *, rn = ROW_NUMBER() OVER 
    (PARTITION BY VendorID, RegionID, Name, Zip 
    ORDER BY AgencyID) FROM dbo.tblAgencies 
) 
DELETE x WHERE rn > 1; 

但要小心;如果其他表參考AgencyID 他們已經獲得您的任何新的錯誤值,則此功能可能無效。

0
;with CTE 
AS 
(
    SELECT ID_Column, rn = ROW_NUMBER() OVER (PARTITION BY Column1, Column2, Column3... ORDER BY ID ASC) 
    FROM T 
) 
DELETE FROM CTE 
WHERE rn >= 2 
0
;with CTE 
AS 
(SELECT MAX(AgencyID) AgentID,VendorID , 
RegionID , 
Name , 
Zip FROM tblAgencies 
GROUP BY VendorID , 
RegionID , 
Name , 
Zip 
HAVING COUNT(*) > 1) 

DELETE FROM tblAgencies WHERE EXISTS (SELECT 1 FROM CTE 
WHERE AgentID = tblAgencies.AgencyID) 
0

很多答案,會給你想要的東西在這裏,但沒有必要使用CTE或做任何分組的,最簡單的方法就是:

delete t1 
from  tblAgencies t1 
join  tblAgencies t2 
on  t1.VendorId = t2.VendorId 
and  t1.RegionId = t2.RegionId 
and  t1.Name = t2.Name 
and  t1.Zip = t2.Zip 
and  t1.AgencyId > t2.AgencyId