Удалить дубликаты записей из таблицы SQL без первичного ключа - PullRequest
49 голосов
/ 12 июня 2009

У меня есть таблица ниже с записями ниже

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

Может ли кто-нибудь помочь мне создать запрос на удаление этих дубликатов записей? 1008 *

Заранее спасибо

Ответы [ 18 ]

71 голосов
/ 12 сентября 2011

Это очень просто. Я пробовал в 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
53 голосов
/ 12 июня 2009

Добавить первичный ключ (код ниже)

Запустите правильное удаление (код ниже)

Подумайте, ПОЧЕМУ вы не хотите сохранять этот первичный ключ.

<ч />

Предполагается, что 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
22 голосов
/ 12 июня 2009

Используйте номер строки, чтобы различать дубликаты записей. Сохраните номер первого ряда для 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 )
9 голосов
/ 06 декабря 2011
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 ;

Это обновит таблицу и удалит все дубликаты из таблицы!

7 голосов
/ 20 июня 2012
select distinct * into newtablename from oldtablename

Теперь у newtablename не будет дублирующихся записей.

Просто измените имя таблицы (newtablename), нажав F2 в проводнике объектов на сервере SQL.

6 голосов
/ 12 июня 2009

Вы можете создать временную таблицу #tempemployee, содержащую select distinct вашей таблицы employee. Тогда delete from employee. Тогда insert into employee select from #tempemployee.

Как сказал Джош, - даже если вы знаете дубликаты , их удаление будет невозможным, поскольку вы не можете фактически ссылаться на конкретную запись, если она является точной копией другой записи.

3 голосов
/ 27 сентября 2016

Код

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 необходимо для правильного синтаксиса; Вы можете поставить любое имя столбца здесь. Если вы хотите изменить, какой из результатов рассматривается как дубликат (например, сохранить самый ранний или самый последний и т. Д.), То столбцы, используемые здесь, имеют значение; то есть вы хотите указать порядок так, чтобы запись, которую вы хотите сохранить, была первой в результате.

2 голосов
/ 19 сентября 2016

ЕГО легко использовать под запросом

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 голосов
/ 03 июня 2010

Если вы не хотите создавать новый первичный ключ, вы можете использовать команду TOP в SQL Server:

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
0 голосов
/ 28 ноября 2018

удалить подпункт из подпункта (выберите ROW_NUMBER () OVer (Разделение по порядку empid по empid) cnt из сотрудника) где sub.cnt> 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...