102

EmployeeNametableという名前の列を考えてみましょうEmployeeEmployeeName目標は、フィールドに基づいて繰り返しレコードを削除することです。

EmployeeName
------------
Anand
Anand
Anil
Dipak
Anil
Dipak
Dipak
Anil

1 つのクエリを使用して、繰り返されるレコードを削除したいと考えています。

これは SQL Server の TSQL でどのように行うことができますか?

4

10 に答える 10

237

ウィンドウ関数でこれを行うことができます。重複を empId で並べ替え、最初のものを除くすべてを削除します。

delete x from (
  select *, rn=row_number() over (partition by EmployeeName order by empId)
  from Employee 
) x
where rn > 1;

選択として実行して、何が削除されるかを確認します。

select *
from (
  select *, rn=row_number() over (partition by EmployeeName order by empId)
  from Employee 
) x
where rn > 1;
于 2010-07-23T15:22:00.997 に答える
38

Employee テーブルにも一意の列があると仮定すると (ID以下の例)、次のように動作します。

delete from Employee 
where ID not in
(
    select min(ID)
    from Employee 
    group by EmployeeName 
);

これにより、テーブル内の ID が最も小さいバージョンが残ります。


Re McGyver のコメントを編集- SQL 2012時点

MIN数値、char、varchar、uniqueidentifier、または datetime 列で使用できますが、ビット列では使用できません

2008 R2以前の場合、

MIN は、numeric、char、varchar、または datetime 列で使用できますが、bit 列では使用できません (また、GUID では機能しません)。

2008R2 では、GUIDを でサポートされている型にキャストする必要があります。MIN

delete from GuidEmployees
where CAST(ID AS binary(16)) not in
(
    select min(CAST(ID AS binary(16)))
    from GuidEmployees
    group by EmployeeName 
);

Sql 2008 のさまざまな型の SqlFiddle

Sql 2012 のさまざまな型の SqlFiddle

于 2010-07-23T11:07:58.810 に答える
8

次のようなことを試すことができます。

delete T1
from MyTable T1, MyTable T2
where T1.dupField = T2.dupField
and T1.uniqueField > T2.uniqueField  

(これは、整数ベースの一意のフィールドがあることを前提としています)

個人的には、修正後の操作としてではなく、重複するエントリがデータベースに追加されているという事実を、それが発生する前に修正しようとしたほうがよいと思います。

于 2010-07-23T11:02:17.230 に答える
3
WITH CTE AS
(
   SELECT EmployeeName, 
          ROW_NUMBER() OVER(PARTITION BY EmployeeName ORDER BY EmployeeName) AS R
   FROM employee_table
)
DELETE CTE WHERE R > 1;

共通テーブル式の魔法。

于 2010-07-25T11:30:41.483 に答える
3
DELETE
FROM MyTable
WHERE ID NOT IN (
     SELECT MAX(ID)
     FROM MyTable
     GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)

WITH TempUsers (FirstName, LastName, duplicateRecordCount)
AS
(
    SELECT FirstName, LastName,
    ROW_NUMBER() OVER (PARTITIONBY FirstName, LastName ORDERBY FirstName) AS duplicateRecordCount
    FROM dbo.Users
)
DELETE
FROM TempUsers
WHERE duplicateRecordCount > 1
于 2013-05-20T10:32:57.987 に答える
1

重複を削除する方法を探しているが、重複のあるテーブルを指している外部キーがある場合は、遅いが効果的なカーソルを使用して次のアプローチをとることができます。

外部キー テーブルの重複キーを再配置します。

create table #properOlvChangeCodes(
    id int not null,
    name nvarchar(max) not null
)

DECLARE @name VARCHAR(MAX);
DECLARE @id INT;
DECLARE @newid INT;
DECLARE @oldid INT;

DECLARE OLVTRCCursor CURSOR FOR SELECT id, name FROM Sales_OrderLineVersionChangeReasonCode; 
OPEN OLVTRCCursor;
FETCH NEXT FROM OLVTRCCursor INTO @id, @name;
WHILE @@FETCH_STATUS = 0  
BEGIN  
        -- determine if it should be replaced (is already in temptable with name)
        if(exists(select * from #properOlvChangeCodes where Name=@name)) begin
            -- if it is, finds its id
            Select  top 1 @newid = id
            from    Sales_OrderLineVersionChangeReasonCode
            where   Name = @name

            -- replace terminationreasoncodeid in olv for the new terminationreasoncodeid
            update Sales_OrderLineVersion set ChangeReasonCodeId = @newid where ChangeReasonCodeId = @id

            -- delete the record from the terminationreasoncode
            delete from Sales_OrderLineVersionChangeReasonCode where Id = @id
        end else begin
            -- insert into temp table if new
            insert into #properOlvChangeCodes(Id, name)
            values(@id, @name)
        end

        FETCH NEXT FROM OLVTRCCursor INTO @id, @name;
END;
CLOSE OLVTRCCursor;
DEALLOCATE OLVTRCCursor;

drop table #properOlvChangeCodes
于 2016-09-28T06:57:47.280 に答える
1

試す

DELETE
FROM employee
WHERE rowid NOT IN (SELECT MAX(rowid) FROM employee
GROUP BY EmployeeName);
于 2013-10-02T10:32:20.433 に答える
0
delete from person 
where ID not in
(
        select t.id from 
        (select min(ID) as id from person 
         group by email 
        ) as t
);
于 2019-10-21T13:59:10.757 に答える
-1

下記の削除方法もあわせてご覧ください。

Declare @Employee table (EmployeeName varchar(10))

Insert into @Employee values 
('Anand'),('Anand'),('Anil'),('Dipak'),
('Anil'),('Dipak'),('Dipak'),('Anil')

Select * from @Employee

ここに画像の説明を入力

という名前のサンプル テーブルを作成し、@Employee指定されたデータをロードしました。

Delete  aliasName from (
Select  *,
        ROW_NUMBER() over (Partition by EmployeeName order by EmployeeName) as rowNumber
From    @Employee) aliasName 
Where   rowNumber > 1

Select * from @Employee

結果:

ここに画像の説明を入力

これは6年前に尋ねられたもので、誰かの役に立つ場合に備えて投稿しています。

于 2016-09-28T10:31:48.533 に答える