2014-12-22 2 views
0

У меня есть таблица с записями:Oracle SQL для удаления дубликатов записей на основе столбцов

DATE   NAME AGE ADDRESS 
01/13/2014  abc  27  us 
01/29/2014  abc  27  ma   <- duplicate 
02/03/2014  abc  27  ny   <- duplicate 
02/03/2014  def  28  ca 

Я хочу, чтобы удалить номер записи 2 и 3, так как они являются дубликатами для записи 1, основанные на имя и возраст. Столбец DATE - это метка времени, основанная на записи, когда она была добавлена ​​(дата sql), и считается уникальной.

Я нашел этот SQL, но не уверен, что если он будет работать, и немного обеспокоен тем, как таблица имеет 2 миллиона записей и delting неправильные будет плохая идея:

SELECT A.DATE, A.NAME, A.AGE 
    FROM table A 
WHERE EXISTS (SELECT B.DATE 
      FROM table B 
      WHERE B.NAME = A.NAME 
      AND B.AGE = A.AGE); 

Есть много экземпляр этого так что если кто-то может помочь мне написать sql для удаления этих записей?

+2

который 'DBMS' вы действительно используете ??? –

+0

В заголовке вы указываете oracle и mysql и sql-server как теги. Какой из них вам действительно нужен? – Wanderer

+1

Я использую разработчика oracle sql для просмотра таблиц. Я только что видел заявление sql и задаюсь вопросом, сработает ли он. –

ответ

0

Запрос

DELETE FROM tbl t1 
WHERE dt IN 
(
    SELECT t1.dt 
    FROM tbl t1 
    JOIN tbl t2 ON 
    (
    t2.name = t1.name 
    AND t2.age=t1.age 
    AND t2.dt > t1.dt 
) 
); 

Fiddle demo

0
delete from table 
where (date, name, age) not in (select max(date), name, age from table group by name, age) 

Перед удалить проверить с

select * from table 
where (date, name, age) not in (select max(date), name, age from table group by name, age) 
0

ROW_NUMBER аналитическая функция поможет (поддерживается Oracle и Sqlserver).
Логика назначения уникального упорядоченного номера для каждой строки внутри раздела должна быть тщательно реализована внутри предложения ORDER BY.

SELECT A_TABLE.*, 
     ROW_NUMBER() 
     OVER (PARTITION BY NAME, AGE 
       ORDER  BY DATE DESC) 
      seq_no 
FROM A_TABLE; 

Затем вы можете использовать результат для операции удаления:

Delete A_TABLE 
where DATE,NAME,AGE IN 
(
    SELECT DATE,NAME,AGE FROM 
    (
     SELECT A_TABLE.*, 
      ROW_NUMBER() 
      OVER (PARTITION BY NAME, AGE 
       ORDER  BY DATE DESC) 
       seq_no 
     FROM A_TABLE; 
    ) 
    WHERE seq_no != 1 
)  
Смежные вопросы