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