如何從 SQL Server 中的資料表中移除重複的資料列

文章翻譯 文章翻譯
文章編號: 139444 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

結論

Microsoft SQL Server 資料表應該永遠不會包含重複資料列,也非唯一的主索引鍵。為了保持簡潔,我們會有時參照至主索引鍵為"索引鍵 」 或 PK"本文章中但是這將會永遠表示 「 主索引]。 重複 PKs 實體完整性的違規情形,而且應該不允許在關聯式系統中。SQL Server 具有各種機制對於強制實體完整性包括索引、 UNIQUE 條件約束、 主索引鍵條件約束與觸發程序。

儘管這,不尋常的情況下重複的主索引鍵而且可能會發生,如果是,它們必須消滅他們。它們可以發生的方法之一是重複 PKs 存在於 SQL Server 外的非關聯式資料,並且 PK 唯一性不被實施時,資料匯入。它們可以發生的另一種方式是透過如不強制執行每個資料表上的實體完整性資料庫設計錯誤。

通常當您嘗試建立將會中止如果找不到重複的索引鍵上一個唯一索引時,會注意到重複 PKs。這個訊息是:
訊息 1505,層級 16 狀態 1 建立唯一索引中止重複的索引鍵。
如果您使用的 SQL Server 2000 或 SQL Server 2005,可能會收到下列錯誤訊息:
msg 1505,層級 16 狀態 1 CREATE UNIQUE INDEX 終止,因為找不到物件名稱的重複索引鍵 ' %* ls' '和索引名稱' %*! ''。 重複的關鍵值是 %1!。
本文將告訴您,如何找出並從資料表移除重複的主索引鍵。但是,您密切應該檢查處理程序允許發生避免了循環重複項目。

其他相關資訊

為使本範例中,我們將使用下列的表格具有重複 PK 值。 此表格中主索引鍵會是兩個資料行 (col1、 col2)。因為兩個資料列擁有重複 PKs,我們無法建立唯一索引或主索引鍵條件約束。這個程序說明如何識別並移除重複的項目。
create table t1(col1 int, col2 int, col3 char(50))
insert into t1 values (1, 1, 'data value one')
insert into t1 values (1, 1, 'data value one')
insert into t1 values (1, 2, 'data value two')
				
第一個步驟是識別哪些資料列擁有重複主索引鍵值:
SELECT col1, col2, count(*)
FROM t1
GROUP BY col1, col2
HAVING count(*) > 1
				
這會傳回每一組的重複 PK 值的一資料列在資料表中。 此結果中的最後一欄是特定 PK 值重複的項目數目。

摺疊此表格展開此表格
col1col2
112


如果個只有少數組的重複 PK 數值最佳的程序就是刪除這些個別的基礎上,手動。例如:
set rowcount 1
delete from t1
where col1=1 and col2=1
				
的資料列計數值應為 n-1 的重複指定的機碼值的項目數目。在這個範例有 2 重複因此資料列計數設為 1。col1/col2 值取自上述 GROUP BY 查詢結果。如果 GROUP BY 查詢傳回多個資料列,"設定資料列計數 」 查詢必須執行一次每個這些資料列。每次執行它會設定資料列計數為 n-1 的特定 PK 值重複的項目數目。

在刪除資料列前您應該驗證整個資料列重複。雖然不太可能,很可能 PK 值是重複,但不是整個列。這個範例是具有身份證字號作為主索引鍵的資料表和相同號碼的有兩個不同的人 (或列),各有獨特的屬性。在這種情況下任何發生故障造成重複的索引鍵有也可能造成有效唯一的資料放到列中。此資料應複製,並且保留之前要刪除資料的研究,並儘可能對帳。

如果個許多不同資料表中的重複 PK 值組可能是太耗費時間分別移除它們。在這種情況下可使用下列程序:
  1. 首先,執行上述 GROUP BY 查詢來決定有多少組重複 PK 值,與每一組重複的項目計數。
  2. 選取 [至控股資料表的 [重複的索引鍵值]。例如:
    SELECT col1, col2, col3=count(*)
    INTO holdkey
    FROM t1
    GROUP BY col1, col2
    HAVING count(*) > 1
    					
  3. 選取 [至控股資料表去除重複項目程序中的 [重複的資料列]。例如:
    SELECT DISTINCT t1.*
    INTO holddups
    FROM t1, holdkey
    WHERE t1.col1 = holdkey.col1
    AND t1.col2 = holdkey.col2
    					
  4. 這個時候 holddups 資料表應該有唯一 PKs,但是,這將不會被寫如果 t1 具有重複 PKs 但唯一的資料列 (做為身份證上述範例中)。請確認 holddups 中的每個機碼唯一,且並不具有重複的索引鍵,但唯一的資料列。如果所以,您必須在此停止並調解資料列的哪一個您想要保留一個給定的重複索引鍵值。比方說查詢:
    SELECT col1, col2, count(*)
    FROM holddups
    GROUP BY col1, col2
    						
    應傳回每個資料列 1 的計數。如果是,繼續進行下面步驟 5。如果沒有,您擁有重複的索引鍵,但唯一的資料列,並且需要決定要儲存哪些資料列。這通常會留下捨棄一列,或建立唯一索引鍵的新值這個資料列。對 holddups 資料表中每一個這類重複 PK 採取其中一個這兩個步驟。
  5. 從原始資料表刪除重複的資料列。例如:
    DELETE t1
    FROM t1, holdkey
    WHERE t1.col1 = holdkey.col1
    AND t1.col2 = holdkey.col2
    					
  6. 將唯一的資料列放回在原始的資料表。例如:
    INSERT t1 SELECT * FROM holddups
    					

屬性

文章編號: 139444 - 上次校閱: 2005年11月23日 - 版次: 4.2
這篇文章中的資訊適用於:
  • Microsoft SQL Server 6.0 Standard Edition
  • Microsoft SQL Server 6.5 Standard Edition
  • Microsoft SQL Server 7.0 Standard Edition
  • Microsoft SQL Server 2000 Standard Edition
  • Microsoft SQL Server 2005 Standard Edition
  • Microsoft SQL Server 2005 Express Edition
  • Microsoft SQL Server 2005 Developer Edition
  • Microsoft SQL Server 2005 Enterprise Edition
  • Microsoft SQL Server 2005 Workgroup Edition
關鍵字:?
kbmt kbinfo kbusage KB139444 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:139444
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com