web-dev-qa-db-ja.com

主キーなしでSQLテーブルから重複レコードを削除する

下の表には、下のレコードが含まれています

create table employee
(
 EmpId number,
 EmpName varchar2(10),
 EmpSSN varchar2(11)
);

insert into employee values(1, 'Jack', '555-55-5555');
insert into employee values (2, 'Joe', '555-56-5555');
insert into employee values (3, 'Fred', '555-57-5555');
insert into employee values (4, 'Mike', '555-58-5555');
insert into employee values (5, 'Cathy', '555-59-5555');
insert into employee values (6, 'Lisa', '555-70-5555');
insert into employee values (1, 'Jack', '555-55-5555');
insert into employee values (4, 'Mike', '555-58-5555');
insert into employee values (5, 'Cathy', '555-59-5555');
insert into employee values (6 ,'Lisa', '555-70-5555');
insert into employee values (5, 'Cathy', '555-59-5555');
insert into employee values (6, 'Lisa', '555-70-5555');

このテーブルには主キーはありませんが、上記のレコードはすでにテーブルにあります。 EmpIdフィールドとEmpSSNフィールドに同じ値を持つ重複レコードを削除したい。

例:Emp id 5

これらの重複レコードを削除するクエリを作成するのを手伝ってくれる人はいますか

前もって感謝します

50
Shyju

主キーを追加します(以下のコード)

正しい削除を実行します(以下のコード)

その主キーを保持したくない理由を検討してください。


MSSQLまたは互換性があると仮定した場合:

ALTER TABLE Employee ADD EmployeeID int identity(1,1) PRIMARY KEY;

WHILE EXISTS (SELECT COUNT(*) FROM Employee GROUP BY EmpID, EmpSSN HAVING COUNT(*) > 1)
BEGIN
    DELETE FROM Employee WHERE EmployeeID IN 
    (
        SELECT MIN(EmployeeID) as [DeleteID]
        FROM Employee
        GROUP BY EmpID, EmpSSN
        HAVING COUNT(*) > 1
    )
END
54
cjk

とても簡単です。 SQL Server 2008で試しました

DELETE SUB FROM
(SELECT ROW_NUMBER() OVER (PARTITION BY EmpId, EmpName, EmpSSN ORDER BY EmpId) cnt
 FROM Employee) SUB
WHERE SUB.cnt > 1
71
Anjib Rajkhowa

行番号を使用して、重複レコードを区別します。 EmpID/EmpSSNの最初の行番号を保持し、残りを削除します。

    DELETE FROM Employee a
     WHERE ROW_NUMBER() <> ( SELECT MIN( ROW_NUMBER() )
                               FROM Employee b
                              WHERE a.EmpID  = b.EmpID
                                AND a.EmpSSN = b.EmpSSN )
22
Paul Morgan
With duplicates

As
(Select *, ROW_NUMBER() Over (PARTITION by EmpID,EmpSSN Order by EmpID,EmpSSN) as Duplicate From Employee)

delete From duplicates

Where Duplicate > 1 ;

これにより、テーブルが更新され、テーブルからすべての重複が削除されます!

9
Nirav Parikh
select distinct * into newtablename from oldtablename

これで、newtablenameには重複したレコードがなくなります。

SQLサーバーのオブジェクトエクスプローラーでF2を押して、テーブル名(newtablename)を変更します。

7

employeeテーブルの#tempemployeeを含む一時テーブルselect distinctを作成できます。次にdelete from employee。次にinsert into employee select from #tempemployee

ジョシュが言ったように、duplicatesを知っていても、特定のレコードが別のレコードの完全な複製である場合、実際に特定のレコードを参照することはできないため、削除は不可能です。

6
Daren Thomas

コード

_DELETE DUP 
FROM 
( 
    SELECT ROW_NUMBER() OVER (PARTITION BY Clientid ORDER BY Clientid ) AS Val 
    FROM ClientMaster 
) DUP 
WHERE DUP.Val > 1
_

説明

内部クエリを使用して、Row_Number()に基づくフィールドを含むテーブル上にビューを作成し、一意にする列でパーティション分割します。

この内部クエリの結果から削除し、行番号が1でないものを選択します。すなわち、重複;オリジナルではありません。

有効な構文には、row_numberウィンドウ関数の_order by_句が必要です。ここに任意の列名を入力できます。どの結果を重複として処理するかを変更する場合(たとえば、最も古いものや最新のものを保持するなど)、ここで使用する列は重要です。つまり、保持するレコードが結果の最初に来るように順序を指定する必要があります。

3
kamz kamarajan

クエリの下のITSの簡単な使用

WITH Dups AS
(
  SELECT col1,col2,col3,
ROW_NUMBER() OVER(PARTITION BY col1,col2,col3 ORDER BY (SELECT 0)) AS rn
 FROM mytable
)
DELETE FROM Dups WHERE rn > 1
2

新しい主キーを作成したくない場合は、SQL ServerでTOPコマンドを使用できます。

declare @ID int
while EXISTS(select count(*) from Employee group by EmpId having count(*)> 1)
begin
    select top 1 @ID = EmpId
    from Employee 
    group by EmpId
    having count(*) > 1

    DELETE TOP(1) FROM Employee WHERE EmpId = @ID
end
2
Joe

主キーのないデータベーステーブルを持っていることは実際にあり、非常に悪い練習と言えます...だからあなたが1つを追加した後(ALTER TABLE)

重複するレコードが表示されなくなるまでこれを実行します(これがCOUNTの目的です)。

DELETE FROM [TABLE_NAME] WHERE [Id] IN 
(
    SELECT MAX([Id])
    FROM [TABLE_NAME]
    GROUP BY [TARGET_COLUMN]
    HAVING COUNT(*) > 1
)


SELECT MAX([Id]),[TABLE_NAME], COUNT(*) AS dupeCount
FROM [TABLE_NAME]
GROUP BY [TABLE_NAME]
HAVING COUNT(*) > 1

MAX([Id])は、最初のレコードを削除する必要があり、最後のレコードを挿入したままにする場合はMIN([Id])を使用するという逆の意味が必要な場合、最新のレコード(最初に作成した後に追加されたもの)を削除します

0
d1jhoni1b

IDrowcount()、_temp table必要です...

WHILE 
  (
     SELECT  COUNT(*) 
     FROM TBLEMP  
     WHERE EMPNO 
            IN (SELECT empno  from tblemp group by empno having count(empno)>1)) > 1 


DELETE top(1)  
FROM TBLEMP 
WHERE EMPNO IN (SELECT empno  from tblemp group by empno having count(empno)>1)
0
Ashish Sahu

私はSQLの専門家ではありませんので、ご容赦ください。すぐにもっと良い答えが得られると確信しています。重複したレコードを見つける方法は次のとおりです。

select t1.empid, t1.empssn, count(*)
from employee as t1 
inner join employee as t2 on (t1.empid=t2.empid and t1.empssn = t2.empssn)
group by t1.empid, t1.empssn
having count(*) > 1

重複を区別するために削除ステートメントで使用できるデータには何もないため、それらを削除することはよりトリッキーになります。答えにはrow_number()またはID列の追加が含まれると思われます。

0
Josh

テーブルIDと名前には2つの列があり、名前が異なるIDで繰り返されているため、次のクエリを使用できます。 。

DELETE FROM dbo.tbl1
WHERE id NOT IN (
     Select MIN(Id) AS namecount FROM tbl1
     GROUP BY Name
)
0
user2497372
ignore_dup_keyを使用して、従業員(EmpId、EmpSSN)
に一意のクラスター化インデックスEmployee_idx 
を作成します

必要ない場合は、インデックスを削除できます。

0
Sudhir

subを削除します(ROW_NUMBER()OVer(empidによるパーティション、empidによる順序)cnt from employee)subを選択します。sub.cnt> 1

0
Sudhar P