2013-01-21 27 views
1

我正在使用SQL Server Management Studio 2012.我有一個包含數千行數據的表。許多行都是重複的,我需要刪除它們。每行都有一個唯一標識[OwnerID],它被設置爲標識增量爲1的標識規範。對於每一行,這些副本位於這些列中:[FirstName],[LastName][CompanyName]刪除基於多列的非獨立行

所以我需要刪除這些3列中具有重複值組合的行。刪除後,是否可以寫t-sql來重置身份規範 [OwnerID]從1開始爲第一行並以1爲增量爲其餘行分配值?

感謝您的任何幫助。

+1

這很容易做到。你有什麼嘗試?我可以給你一些指導:首先:創建一個由[FirstName],[LastName]和[CompanyName]分組的Select語句,並將其插入臨時表。接下來,TRUNCATE你的表格。然後,從臨時表中插入到截斷的表中的數據。之後放下臨時表。當您截斷表時,身份重置 – cha

+0

爲什麼您需要重置身份並小心處理此問題。如果你將它們重置爲順序並且它們被用作其他表的外鍵,那麼你就失去了關係。此外,如果刪除重複項和重複項已用於關係中,則可能需要將關係設置爲將保留的記錄的標識。這裏有很多風險獎勵什麼? – xQbert

+0

好吧,我忘了補充說有外鍵關係到其他表。目標是每個唯一的所有者只有一行。現在,由於我剛剛導入了一堆垃圾數據,因此有多行具有相同的所有者'[FirstName]','[LastName]'和'[CompanyName]'。我只需要一種方法來刪除這些。我不知道該怎麼做,所以我還沒有嘗試過任何東西。 @Cha,你能更具體地說明我需要如何編碼嗎?我想我並不需要重置身份規範,我只是認爲它看起來更乾淨。 – leschandrew

回答

0

下面是使用臨時表SQL Fiddle我嘗試:

SELECT 
firstName, LastName, CompanyName, COUNT(*) thecount, MIN(ID) min_id 
INTO #temp 
FROM tab 
GROUP BY firstName, LastName, CompanyName; 

SELECT 
a.id ID, b.min_id 
INTO #temp1 
FROM tab a, #temp b 
WHERE a.firstName = b.FirstName 
AND a.LastName = b.LastName 
AND a.CompanyName = b.CompanyName 
AND b.thecount > 1; 

-- run this query on all referenced tables: 
UPDATE tab2 SET tab2.ID = t.min_id 
FROM tab2, #temp1 t 
WHERE tab2.ID = t.ID; 

DELETE t 
FROM tab t, #temp1 a 
WHERE t.id = a.id and a.id <> a.min_id; 
0

這裏是刪除行的一種方式,通過使用row_number()保持第一位:

with todelete as (
    select t.*, 
      row_number() over (partition by firstname, lastname, companyname 
           order by ownerid) as seqnum 
    from t 
) 
delete from todelete 
    where seqnum = 1; 

要重置OWNERID,你也可以使用一個類似的想法:

with toupdate as (
    select t.*, row_number() over (order by ownerid) as seqnum 
    from t 
    ) 
update toupdate 
    set ownerid = seqnum; 

然而,你應該非常小心。在設計良好的數據庫中,名爲OwnerID的字段將引用表中名爲Owner.OwnerIdOwner.Id的列。更改ID的值可能會影響其他表。

0
如果你想刪除重複的數據,並保持一個值,使用此查詢用逗號將多個列分隔

從刪除

( select *,rn = row_number()over(由MemberId按名字排序的分區) 來自成員資格 )a 其中rn> 1;