2010-02-03 4 views
2

Как удалить дубликаты записей в sql?Как удалить дубликаты записей в SQL

+2

Как вам знаете, что они дубликаты? – APC

+1

Как вы получили дубликаты в первую очередь? У вас нет ограничений на уникальность? Как насчет ПК? Каково ваше определение «дубликат»? –

+0

Столбцы и примеры данных. –

ответ

4

Вот как это сделать в Oracle, используя ROWID. Различные вкусы РСУБД будут иметь свой собственный эквивалент.

Я начинаю с создания некоторых повторяющихся записей ...

SQL> select t, count(*) from t23 group by t; 

T  COUNT(*) 
----- ---------- 
09:00   2 
12:00   2 
10:30   2 
11:00   2 
12:30   2 
08:00   2 
10:45   2 
11:15   2 

8 rows selected. 

SQL> 

... и теперь я зап их, используя T для определения "повторяющихся записей" ...

SQL> delete from t23 
    2 where rowid > (select min(rowid) from t23 x 
    3     where x.t = t23.t) 
    4/

8 rows deleted. 

SQL> select t, count(*) from t23 group by t; 

T  COUNT(*) 
----- ---------- 
09:00   1 
12:00   1 
10:30   1 
11:00   1 
12:30   1 
08:00   1 
10:45   1 
11:15   1 

8 rows selected. 

SQL> 

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

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

+0

+1 для упоминания о создании какой-то уникальности строк – Matt

-2

выбрать col from table;

отличные col from table;

+2

Он сказал * удалите * дубликаты, а не только * избегайте выбора * их. – smci

3

Поскольку у вас нет ключа на столе (при условии, что ваши строки дублируются на 100%), у вас не будет проблем с другими таблицами, ссылающимися на вашу таблицу с помощью FOREIGN KEY.

Самый быстрый и наименее сложный способ сделать это:

SELECT DISTINCT * 
INTO #tmp 
FROM YourTable; 

TRUNCATE TABLE YourTable; 

INSERT YourTable 
SELECT * from #tmp; 

Может быть, рассмотреть вопрос о добавлении некоторой версии этого заявления до конца ;-)

ALTER YourTable ADD CONSTRAINT PK_YourTable PRIMARY KEY (whatever, keeps, this, from, happening, again); 
7

В SQL Server 2005 и выше:

WITH q AS 
     (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY dup_column ORDER BY dup_column) AS rn 
     FROM mytable 
     ) 
DELETE 
FROM q 
WHERE rn > 1 
+0

отличная статья в блоге об этом: http://explainextended.com/2009/03/14/deleting-duplicates/ –

+0

huh. никогда не думал, что это будет разрешено ... но вот и вот, это работает. +1 –

+0

@KM: Думаю, мне нужно его прочитать! :) – Quassnoi

0

В Postgresql я использую следующее:

DELETE FROM table_name q 
WHERE EXISTS (
    SELECT 1 
    FROM table_name q1 
    WHERE q1.ctid < q.ctid 
    AND q.fid = q1.fid 
    ); 

Где fid - ваш уникальный идентификационный номер или первичный ключ.

0

В MS SQL,

DELETE Table1 FROM Table1 
INNER JOIN ( 
    SELECT MAX(lineitem) AS lineitem, ID, COUNT (ID) AS IDCount 
    FROM Table1 
    GROUP BY ID HAVING COUNT (ID) > 1) AS Table2 
ON Table1.ID = Table2.ID and Table1.LineItem = Table2.lineitem 

Над SQL будет найти все дубликаты ID и удалить один с максимальной LineItem.

ID   LineItem 
---  -------- 
111  1 
111  2 (Deleted) 
222  1 
222  2 (Deleted) 
0

В Oracle мы можем сделать это, используя множество способов.

1) путем создания новой таблицы:

create table emp2 as 
select distinct * from EMP; 
drop table emp; 
alter table emp2 rename to emp; 

2) Использование RowId:

delete from EMP where rowid not in (
select max(rowid) from EMP group by EMPNO, EMPNAME, SALARY); 

3) Используя автообъединение и RowID:

delete from emp e1 where rowid not in(
select max(rowid) from EMP e2 
where e1.EMPNO = e2.EMPNO); 
Смежные вопросы