57

以下のレコードを含む以下の表があります

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

誰かがそれらの重複レコードを削除するためのクエリを組み立てるのを手伝ってくれますか?

前もって感謝します

4

19 に答える 19

83

とても簡単です。SQLServer2008で試しました

DELETE SUB FROM
(SELECT ROW_NUMBER() OVER (PARTITION BY EmpId, EmpName, EmpSSN ORDER BY EmpId) cnt
 FROM Employee) SUB
WHERE SUB.cnt > 1
于 2011-09-12T12:22:38.567 に答える
59

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

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

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


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
于 2009-06-12T07:23:19.373 に答える
24

行番号を使用して、重複するレコードを区別します。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 )
于 2009-06-12T17:01:50.077 に答える
12
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 ;

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

于 2011-12-06T16:38:02.083 に答える
8
select distinct * into newtablename from oldtablename

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

newtablenameSQL ServerのオブジェクトエクスプローラーでF2キーを押して、テーブル名()を変更するだけです。

于 2012-06-20T11:57:16.330 に答える
7

コード

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でないものを選択します。つまり、重複。オリジナルではありません。

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

于 2016-09-27T06:40:21.370 に答える
6

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

Joshが言ったように、重複を知っていても、別のレコードの正確な重複である場合、特定のレコードを実際に参照することはできないため、それらを削除することは不可能です。

于 2009-06-12T07:16:34.740 に答える
2

新しい主キーを作成したくない場合は、SQLServerで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
于 2010-06-02T21:30:41.073 に答える
2

クエリの下での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
于 2016-09-19T10:20:10.480 に答える
1

subを削除します(select ROW_NUMBER()OVer(Partition by empid order by empid)cnt from employee)sub where sub.cnt> 1

于 2018-11-28T03:24:46.680 に答える
0

私は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

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

于 2009-06-12T07:18:02.087 に答える
0
一意のクラスター化インデックスEmployee_idxを作成します
on Employee(EmpId、EmpSSN)
ignore_dup_keyで

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

于 2010-07-16T07:49:11.933 に答える
0

いいえID、いいえ、rowcount()または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)
于 2013-04-14T05:56:16.523 に答える
0

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

DELETE FROM dbo.tbl1
WHERE id NOT IN (
     Select MIN(Id) AS namecount FROM tbl1
     GROUP BY Name
)
于 2013-06-18T13:35:03.700 に答える
0

主キーのないデータベーステーブルを持つことは、実際には非常に悪い習慣です...したがって、主キーを追加した後(ALTER TABLE)

重複したレコードが表示されなくなるまでこれを実行します(これがHAVING 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])を使用してください。

于 2014-07-19T04:08:45.400 に答える
-1
select t1.* from employee t1, employee t2 where t1.empid=t2.empid and t1.empname = t2.empname and t1.salary = t2.salary
group by t1.empid, t1.empname,t1.salary having count(*) > 1
于 2009-10-06T11:52:04.163 に答える
-1

従業員から削除するrowidin(select rowid from(select rowid、name_count from(select rowid、count(emp_name)as name_count from employee group by emp_id、emp_name)where name_count> 1))

于 2020-10-03T16:27:55.090 に答える
-2
DELETE FROM 'test' 
USING 'test' , 'test' as vtable
WHERE test.id>vtable.id and test.common_column=vtable.common_column  

これを使用して、重複するレコードを削除できます

于 2010-11-09T11:04:51.490 に答える
-3
ALTERIGNORETABLEテスト
           一意のインデックスを追加'テスト'('b');

@ here'b'は一意性に対する列名、@here'test'はインデックス名です。

于 2010-11-09T10:18:33.273 に答える