поиск повторяющихся строк в нескольких полях - PullRequest
0 голосов
/ 30 сентября 2011

Я использую этот запрос, чтобы найти дубликаты на основе двух полей:

SELECT 
    last_name, 
    first_name,
    middle_initial,
    COUNT(last_name) AS Duplicates,
    IF(rec_id = '', 1, 0) AS has_REC_ID 
FROM files
GROUP BY last_name, first_name
HAVING COUNT(last_name) > 1 AND COUNT(first_name) > 1;

Хорошо, это возвращает набор строк с именами по имени, фамилии и отчеству, столбец с именем «Duplicates» с множеством 2-х и столбец с именем has_REC_ID со смешанными 1-м и 0-м

В конечном итоге я пытаюсь найти строки с одинаковыми именами и именами, а затем для каждой из этих пар найти ту, которая имеет ('') в качестве значения для rec_id, назначить значение rec_id из того, которое ДОЛЖНО иметь rec_id, а затем удалить запись, у которой во-первых был rec_id.

Итак, для начала я решил создать новую колонку и сделать что-то вроде этого:

UPDATE files a 
SET a.has_dup    --new column
    = if(a.last_name IN (
                         SELECT b.last_name
                         FROM files b
                         GROUP BY b.last_name 
                         HAVING COUNT(b.last_name) > 1
                        )
      , 1, null);

Но MySQL возвращает: «Вы не можете указать целевую таблицу« a »для обновления из предложения from»

Могу поспорить, что есть кое-что гораздо менее смешное, чем метод, который я здесь пробую. Может кто-нибудь, пожалуйста, помогите мне понять, что это такое?

ОБНОВЛЕНИЕ: Я также пытался:

UPDATE files a 
SET a.has_dup = 1
WHERE a.last_name IN (
                         SELECT b.last_name
                         FROM files b
                         GROUP BY b.last_name 
                         HAVING COUNT(b.last_name) > 1
                     );

... и получил то же сообщение об ошибке.

Ответы [ 3 ]

0 голосов
/ 30 сентября 2011

С документация :

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

Я не могу придумать быстрого решения этой проблемы.


Обновление

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

UPDATE files a 
SET a.has_dup    --new column
    = if(a.last_name IN (
                     SELECT b.last_name
                     FROM
                          (SELECT * FROM files)      -- new table target
                     b
                     GROUP BY b.last_name 
                     HAVING COUNT(b.last_name) > 1
                    ),
      1, null);
0 голосов
/ 30 сентября 2011

Вы можете:

1) Создать таблицу хранения

2) Заполнить таблицу хранения теми строками, которые имеют совпадающие имя и фамилию и имеют rec_id! = ""

3) Удалите строки из исходной таблицы (файлов), которые имеют совпадающие имя и фамилию и имеют rec_id! = ""

4) Обновите строки в исходной таблице, которые имеют совпадающиеимя и фамилия и имеют rec_id = "".

5) Удалите удерживающий стол

Так что-то вроде:

create table temp
(
firstname varchar(100) not null,
lastname varchar(100) not null,
rec_id int not null
);


insert into temp (select firstname,lastname,rec_id from files where firstname =    lastname and rec_id != '');


delete from files where firstname = lastname and rec_id != '';

update files f
set f.rec_id = (select t.rec_id from temp t where f.firstname = t.firstname and f.lastname = t.lastname)
where f.firstname = f.lastname 
and f.rec_id != '';


drop table temp;
0 голосов
/ 30 сентября 2011

У меня нет MySQL для тестирования, но я думаю, что это должно работать: (EDITED-> FAIL)

UPDATE files
SET has_dup
    = if(last_name IN (
                         SELECT b.last_name
                         FROM files b
                         GROUP BY b.last_name 
                         HAVING COUNT(b.last_name) > 1
                      )
      , 1, null);

EDITED: еще одна попытка:

UPDATE files f, (SELECT b.last_name
                   FROM files b
               GROUP BY b.last_name 
                 HAVING COUNT(b.last_name) > 1
                ) as duplicates
   SET f.has_dup = 1
 WHERE f.last_name = duplicates.last_name
...