Удалять повторяющиеся записи из таблицы 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.

Ex: Emp id 5

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

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

Ответ 1

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

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

Подумайте, почему вы не хотите хранить этот первичный ключ.


Предполагая 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

Ответ 2

Это очень просто. Я попытался в 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

Ответ 3

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

Ответ 4

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 ;

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

Ответ 5

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

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

Ответ 6

select distinct * into newtablename from oldtablename

Теперь newtablename не будет иметь дубликатов записей.

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

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

Ответ 8

Если вы не хотите создавать новый первичный ключ, вы можете использовать команду 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

Ответ 9

ЕЕ легко использовать ниже запроса

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

Ответ 10

Я не эксперт по 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() или добавление столбца идентификации.

Ответ 11

create unique clustered index Employee_idx
on Employee ( EmpId,EmpSSN )
with ignore_dup_key

Вы можете отбросить индекс, если он вам не нужен.

Ответ 12

no ID, no rowcount() или no 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)

Ответ 13

есть два столбца в идентификаторе таблицы и имени, где имена повторяются с разными идентификаторами, поэтому для этого вы можете использовать этот запрос: , .

DELETE FROM dbo.tbl1
WHERE id NOT IN (
     Select MIN(Id) AS namecount FROM tbl1
     GROUP BY Name
)

Ответ 14

Наличие таблицы базы данных без Первичного ключа действительно и будет говорить предельно БЕСПЛАТНАЯ ПРАКТИКА... поэтому после того, как вы добавите ее (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] )

Ответ 15

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

Ответ 16

DELETE FROM 'test' 
USING 'test' , 'test' as vtable
WHERE test.id>vtable.id and test.common_column=vtable.common_column  

Используя это, мы можем удалить повторяющиеся записи

Ответ 17

ALTER IGNORE TABLE test
           ADD UNIQUE INDEX 'test' ('b'); 

@здесь 'b' - это имя столбца для уникальности, @здесь 'test' - это имя индекса.