2015-11-05 2 views
1

У меня есть таблица с повторяющимися записями (я забыл сделать окнеИМЯстолбец уникальный)Проверить дубликаты в SQL таблицы и заменить дубликаты ID в другой таблице

Так что я теперь есть этот дубликат таблицы запись под названием «Таблица 1»

ID NAME 
1 John F Smith 
2 Sam G Davies 
3 Tom W Mack 
4 Bob W E Jone 
5 Tom W Mack 

И.Е. ID 3 и 5 являются дубликатами

Таблица 2

ID NAMEID   ORDERS 
1 2    item4 
2 1    item5 
3 4    item6 
4 3    item23 
5 5    item34 

NameID являются ID из таблицы 1. Таблица 2 ID 4 и 5 Я хочу иметь NameID 3 (Заказы Tom W Мака), как так

Таблица 2 (правильная версия)

ID NAMEID   ORDERS 
1 2    item4 
2 1    item5 
3 4    item6 
4 3    item23 
5 3    item34 

Есть простой способ найти и обновить дубликаты NAMEID в таблице 2, затем удалить дубликаты из таблицы 1

+0

Если есть только несколько повторяющихся записей, лучшей процедурой является удаление их вручную по отдельности – Matheno

+0

Какая СУБД вы используете? Postgres? Oracle? –

ответ

0

В этом случае вы можете сделать это. Вы можете найти, сколько дублированных записей у вас есть. Чтобы найти дубликаты записей, которые вы можете использовать.

SELECT ID, NAME,COUNT(1) as CNT FROM TABLE1 GROUP BY ID, NAME 

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

Не забудьте изменить таблицу после удаления всех повторяющихся записей.

0

Вот как вы можете это сделать:

-- set up the environment 
create table #t (ID int, NAME varchar(50)) 

insert #t values 
(1, 'John F Smith'), 
(2, 'Sam G Davies'), 
(3, 'Tom W Mack'), 
(4, 'Bob W E Jone'), 
(5, 'Tom W Mack') 

create table #t2 (ID int, NAMEID int, ORDERS varchar(10)) 

insert #t2 values 
(1, 2,    'item4'), 
(2, 1,    'item5'), 
(3, 4,    'item6'), 
(4, 3,    'item23'), 
(5, 5,    'item34') 
go 

-- update the referencing table first 
;with x as (
    select id, 
    first_value(id) over(partition by name order by id) replace_with 
    from #t 
), 
y as (
    select #t2.nameid, x.replace_with 
    FROM #t2 
    join x on #t2.nameid = x.id 
    where #t2.nameid <> x.replace_with 
) 
update y set nameid = replace_with 

-- delete duplicates from referenced table 
;with x as (
    select *, row_number() over(partition by name order by id) rn 
    from #t 
) 
delete x where rn > 1 

select * from #t 
select * from #t2 

Pls, испытание первой производительности и достоверности.

0

Давайте использовать данные примера

INSERT INTO TableA 
    (`ID`, `NAME`) 
VALUES 
    (1, 'NameA'), 
    (2, 'NameB'), 
    (3, 'NameA'), 
    (4, 'NameC'), 
    (5, 'NameB'), 
    (6, 'NameD') 

и

INSERT INTO TableB 
    (`ID`, `NAMEID`, `ORDERS`) 
VALUES 
    (1, 2, 'itemB1'), 
    (2, 1, 'itemA1'), 
    (3, 4, 'itemC1'), 
    (4, 3, 'itemA2'), 
    (5, 5, 'itemB2'), 
    (5, 6, 'itemD1') 

(делает его немного легче обнаружить дубликаты и проверить результат)

Давайте начнем с простого запроса к получите наименьший ID для данного NAME

SELECT 
    NAME, min(ID) 
FROM 
    tableA 
GROUP BY 
    NAME 

И результат [NameA,1], [NameB,2], [NameC,4], [NameD,6]

Теперь, если вы используете это как некоррелированный подзапрос для объединения с базовой таблицей, как

SELECT 
    keep.kid, dup.id 
FROM 
    tableA as dup 
JOIN 
    (
     SELECT 
      NAME, min(ID) as kid 
     FROM 
      tableA 
     GROUP BY 
      NAME 
    ) as keep 
ON 
    keep.NAME=dup.NAME 
    AND keep.kid<dup.id 

Он находит все дубликаты, которые имеют такое же имя, как и в результате подзапрос, но другой id + он также дает вам идентификатор «оригинала», т. е. наименьший идентификатор для этого имени.
Для примера это [1,3], [2,5]

Теперь вы можете использовать это в запросе UPDATE как

UPDATE 
    TableB as b 
JOIN 
    tableA as dup 
JOIN 
    (
     SELECT 
      NAME, min(ID) as kid 
     FROM 
      tableA 
     GROUP BY 
      NAME 
    ) as keep 
ON 
    keep.NAME=dup.NAME 
    AND keep.kid<dup.id 
SET 
    b.NAMEID=keep.kid 
WHERE 
    b.NAMEID=dup.id 

И результат

ID,NAMEID,ORDERS 
1, 2, itemB1 
2, 1, itemA1 
3, 4, itemC1 
4, 1, itemA2 <- now has NAMEID=1 
5, 2, itemB2 <- now has NAMEID=2 
5, 6, itemD1 

Чтобы eleminate дубликаты из TABLEA вы можете использовать первый запрос снова.

Смежные вопросы