EmployeeName
tableという名前の列を考えてみましょうEmployee
。EmployeeName
目標は、フィールドに基づいて繰り返しレコードを削除することです。
EmployeeName
------------
Anand
Anand
Anil
Dipak
Anil
Dipak
Dipak
Anil
1 つのクエリを使用して、繰り返されるレコードを削除したいと考えています。
これは SQL Server の TSQL でどのように行うことができますか?
EmployeeName
tableという名前の列を考えてみましょうEmployee
。EmployeeName
目標は、フィールドに基づいて繰り返しレコードを削除することです。
EmployeeName
------------
Anand
Anand
Anil
Dipak
Anil
Dipak
Dipak
Anil
1 つのクエリを使用して、繰り返されるレコードを削除したいと考えています。
これは SQL Server の TSQL でどのように行うことができますか?
ウィンドウ関数でこれを行うことができます。重複を 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;
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
);
次のようなことを試すことができます。
delete T1
from MyTable T1, MyTable T2
where T1.dupField = T2.dupField
and T1.uniqueField > T2.uniqueField
(これは、整数ベースの一意のフィールドがあることを前提としています)
個人的には、修正後の操作としてではなく、重複するエントリがデータベースに追加されているという事実を、それが発生する前に修正しようとしたほうがよいと思います。
WITH CTE AS
(
SELECT EmployeeName,
ROW_NUMBER() OVER(PARTITION BY EmployeeName ORDER BY EmployeeName) AS R
FROM employee_table
)
DELETE CTE WHERE R > 1;
共通テーブル式の魔法。
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
重複を削除する方法を探しているが、重複のあるテーブルを指している外部キーがある場合は、遅いが効果的なカーソルを使用して次のアプローチをとることができます。
外部キー テーブルの重複キーを再配置します。
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
試す
DELETE
FROM employee
WHERE rowid NOT IN (SELECT MAX(rowid) FROM employee
GROUP BY EmployeeName);
delete from person
where ID not in
(
select t.id from
(select min(ID) as id from person
group by email
) as t
);
下記の削除方法もあわせてご覧ください。
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年前に尋ねられたもので、誰かの役に立つ場合に備えて投稿しています。