2015-11-13 7 views
0

Некоторые строки имеют одинаковые первичные ключи (ID), но остальная часть строки может отличаться. Например,Как удалить повторяющиеся строки

ID Age Info 
2 21 2763 
2 21 6276 
3 31 82756 

В этом случае как первая, так и вторая строки имеют одинаковый идентификатор и возраст, но разные данные. То, что я хочу делать с повторяющимися строками идентификаторов, - это случайное сохранение одного из них и удаление других. У меня так много таких записей в моих наборах данных, поэтому я не могу их удалять один за другим. Есть ли какие-либо решения? Благодаря

+2

Что РСУБД? – SQLChao

+0

, который является вашим основным ключом в этой таблице? – Adish

+0

@Adish PK - это идентификатор в этом примере. Спасибо –

ответ

0

Я думаю, что вы ищете что-то вроде этого:

delete from TableName where info not in 
(select min(info) from TableName group by ID,Age); 

попробовать отборное заявление первого, чтобы убедиться, что возвращается правильные строки добавьте удаления части к нему

+0

Позвольте мне попробовать! Спасибо за ваш ответ! –

+1

Это будет работать, только если 'info' уникален. Строка ID = 2, Info = 82756 выкинула бы ее. –

+0

Правильно, предположение на пример состоит в том, что Info уникальна для каждого сгруппированного идентификатора и возраста. –

1

Попробуйте это:

DELETE t1 
FROM mytable AS t1 
INNER JOIN mytable AS t2 
ON t1.ID = t2.ID AND t1.Age = t2.Age AND t1.Info > t2.Info 

Вышеупомянутый должен работать в MySQL, SQL Server. Оператор удаляет все строки в (ID, Age) фрагменте , но тот, который имеет наименьшее значение Info.

Примечание: Вышеуказанные работы при условии, что значения Info являются уникальными для (ID, Age) среза.

+0

Спасибо за ваш ответ, Что такое t1 и t2? –

+0

@GavinNiu Это псевдонимы для таблиц –

+0

Это не удалит строки, где совпадают идентификаторы, а Age - нет. Это не приведет к удалению строк, где все три столбца идентичны. – Adish

0

Я бы предложил решение на основе набора, но я не мог позаботиться о строках, в которых все 3 строки идентичны. Поэтому предлагая решение, которое использует ROWCOUNT и цикл while. ROWCOUNT гарантирует, что только одна запись будет удалена за раз. Цикл while так, что вам не нужно делать это вручную один за другим.

SET ROWCOUNT 1 

DECLARE @ctr INT 
SELECT TOP 1 @ctr = COUNT(*) FROM table GROUP BY ID HAVING COUNT(*) > 1 ORDER BY COUNT(*) desc 
SELECT @ctr 
WHILE @ctr > 1 
BEGIN 
    DELETE FROM table WHERE ID IN (SELECT ID FROM table GROUP BY ID HAVING COUNT(*) > 1) 
    SELECT @ctr = NULL 
    SELECT TOP 1 @ctr = COUNT(*) FROM table GROUP BY ID HAVING COUNT(*) > 1 ORDER BY COUNT(*) desc 
If @Ctr IS NULL 
    Break 
ELSE 
    Continue 
END 
SET ROWCOUNT 0 

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

+0

Попробуйте это. Сделайте резервную копию перед выполнением. – Adish

1

С функцией окна:

;with cte as(select *, row_number() over(partition by id order by info) rn 
      from table) 
delete from cte where rn <> 1 
Смежные вопросы