2012-06-05 3 views
1

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

| contact_info | icon | id | title   | lastmodified_by | 
+--------------+------+-----+---------------+------------------+ 
|   169 | 305 | 123 | Whakarewarewa | 2011100400305262 | 
|   NULL | NULL | 850 | Whakarewarewa | NULL    | 
+--------------+------+-----+---------------+---------------- 



| contact_info | icon | id | title   | lastmodified_by | 
+--------------+------+-----+---------------+------------------+ 
|   NULL | NULL | 123 | Paris   | NULL    | 
|   NULL | NULL | 850 | Paris   | NULL    | 
+--------------+------+-----+---------------+---------------- 

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

+0

Удалить, где id = 850? – Nanne

+0

Очевидно, что было бы несколько записей, иначе я бы не задал этот вопрос здесь в stackoverflow. –

+0

Этот вопрос был запрошен триллионы времени, [здесь] (http://stackoverflow.com/questions/672702/how-to-delete-duplicates-in-mysql-table), [здесь] (http: // stackoverflow. com/questions/2469006/how-to-delete-duplicates-in-mysql-using-case), [здесь] (http://stackoverflow.com/questions/2630440/how-to-delete-duplicates-on-mysql (здесь) (http://stackoverflow.com/questions/3383898/remove-duplicates-using-only-a-mysql-query), [здесь] (http://stackoverflow.com/questions/6308924/modifying-a-mysql-query-that-removees-duplicates) ... –

ответ

3

Попробуйте это двухступенчатый решение:

Выполнить этот запрос Vew все дубликаты - записи, имеющей меньше данных -

SELECT t1.* FROM table t1 
    JOIN (
    SELECT 
     title, 
     MIN(IF(contact_info IS NULL, 0, 1) + IF(contact_info IS NULL, 0, 1) + IF(lastmodified_by IS NULL, 0, 1)) min_value_data, 
     MAX(IF(contact_info IS NULL, 0, 1) + IF(contact_info IS NULL, 0, 1) + IF(lastmodified_by IS NULL, 0, 1)) max_value_data 
    FROM table GROUP BY title HAVING min_value_data <> max_value_data 
) t2 
    ON t1.title = t2.title AND IF(t1.contact_info IS NULL, 0, 1) + IF(t1.contact_info IS NULL, 0, 1) + IF(t1.lastmodified_by IS NULL, 0, 1) <> t2.max_value_data 

Rewrite это DELETE заявления и выполнить.


Затем запустить этот запрос, чтобы удалить все дубликаты за исключением мин ID:

DELETE t1 FROM table t1 
    JOIN (SELECT MIN(id) id, title FROM table GROUP BY title) t2 
    ON t1.id <> t2.id AND t1.title = t2.title; 
+0

Что делать, если какая-либо запись с минимальным идентификатором не имеет данных, но у max id есть данные. Он удалит id с максимальным id и сохранит id с min id ??? –

+0

Да, вы правы. Я прочитал ваш отредактированный вопрос; и запрос должен быть переписан. – Devart

+0

Я добавил новый запрос. – Devart

1

Используйте это, чтобы выбрать дубликаты, не стесняйтесь, чтобы изменить это к ВЕЬЕТЕ:

SELECT * FROM `test`, 
(SELECT title, count(title) AS ttl 
FROM `test` 
GROUP BY title 
HAVING ttl >1) AS sub 

WHERE test.title = sub.title 
AND contact_info IS NULL AND lastmodified_by IS NULL 
+0

Этот запрос не выполняется в случае, если title = Paris. В нем перечисляются как Париж в результате. Это тот случай, когда оба результата являются точными дубликатами, включая все поля –

+1

Правильно, я не видел ваш пример в Париже. Как об этом: Отображение строки 0 - 1 (2 всего, Запрос занял 0.0007 сек) SELECT * FROM ' test' в качестве основного, ( SELECT, название, кол-(название) КАК ТТЛ ОТ' test' GROUP BY названием HAVING ТТЛ> 1 ) замену ГДЕ main.title = sub.title И main.contact_info IS NULL И main.lastmodified_by IS NULL GROUP BY main.contact_info, main.icon, main.title , main.lastmodified_by –

+0

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

0

Main Таблица = tes1

Создать температуру

CREATE TEMPORARY TABLE my_temp (id INT (20) NOT NULL) ENGINE = MEMORY;

Заполнить с идентификаторами, чтобы удалить

вставить в my_temp (ID) SELECT, идентификатор из tes1 в качестве основного, (SELECT название, граф (название) КАК ТТЛ ОТ tes1 GROUP BY названием HAVING ТТЛ> 1) в качестве суб WHERE main.title = sub.title И main.contact_info IS NULL И main.lastmodified_by IS NULL GROUP BY main.contact_info, main.icon, main.title, main.lastmodified_by;

Удалить!

DELETE FROM tes1 WHERE id IN (выберите id из my_temp);

Очистка, обратите внимание: действительно ли это нужно?

DROP TABLE my_temp;

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