2015-03-26 2 views
0

Прежде всего, я был на этом в течение 2 часов, и я провел полное исследование, прежде чем публиковать его здесь. Здесь есть похожие вопросы, но ни одна из них не соответствует моей проблеме (поэтому, пожалуйста, не отмечайте ее как дубликат).Удалите определенные повторяющиеся строки и сохраните один

У меня есть огромная таблица с более чем 100 000 записей, и я пытаюсь удалить определенные повторяющиеся строки.

Пример я следующие строки:

ID NAME NUMBER 
1 'NIL' 1234 
2 'NIL' 1234 
3 'NIL' 1234 
4 'MES' 5989 
5 'NL' 1235 
6 'NL' 12385 
7 'NL' 1235 
8 'MES' 5989 

Ожидаемый результат (который ID сохранить или какой идентификатор для удаления не имеет значения):

ID NAME NUMBER 
1 'NIL' 1234 
2 'NIL' 1234 
3 'NIL' 1234 
4 'MES' 5989 
5 'NL' 1235 
6 'NL' 12385 

Я попытался это:

DELETE FROM tableA 
WHERE ID NOT IN 
(
    SELECT ID From (SELECT * FROM tableA) AS t1 
    WHERE PHONE NOT IN (1235,5989) 
    GROUP BY NAME, NUMBER 
UNION 
    SELECT MIN(ID) From (SELECT * FROM tableA) AS t2 
    WHERE PHONE IN (1235,5989) 
    GROUP BY NAME, NUMBER 
) 

Приведенный выше запрос работает на тестовых данных 10 или 20 строк, но при применении к живой базе данных требуется возраст и сохраняется выборка (запрос был запущен с более чем 40 минут) Я не знаю, что я делаю неправильно. Любая помощь будет принята с благодарностью.

+0

"(какой идентификатор должен содержать или какой идентификатор для удаления не имеет значения)" Он * должен * иметь значение! – Strawberry

+0

Почему первые три строки не дублируются? – xdazz

+0

@Strawberry Я согласен, но в моем случае это действительно не так. Спасибо –

ответ

0

Я бы поставил внутреннее предложение в таблицу темп и отбирал из этого.

CREATE TEMPORARY TABLE IF NOT EXISTS IdsToKeep AS 
(SELECT ID From (SELECT * FROM tableA) AS t1 
WHERE PHONE NOT IN (1235,5989) 
GROUP BY NAME, NUMBER 
UNION 
SELECT MIN(ID) From (SELECT * FROM tableA) AS t2 
WHERE PHONE IN (1235,5989) 
GROUP BY NAME, NUMBER) 

DELETE FROM tableA 
WHERE ID NOT IN 
(SELECT ID FROM IdsToKeep) 

К сожалению, я не так хорошо знаком с MySql, поэтому синтаксис может немного отличаться.

+0

спасибо. Но причиной использования таблицы temp была Mysql, которая выдала бы ошибку, если я попытаюсь использовать (такое же) имя таблицы, которое должно быть обновлено внутри класса where :( –

+0

@NishanthMatha ОК, я вернул его, как у вас было это (извините за это). Я бы все равно извлек эту часть в временную таблицу заранее, а затем запустил запрос на удаление из таблицы temp. – CindyH

1
CREATE TABLE tableB like tableA; 
INSERT INTO tableB (SELECT * FROM tableA GROUP BY name,number); 
RENAME TABLE tableA to tableA_with_dups, tableB to tableA; 

* обратите внимание, что это не обязательно является лучшим решением, в зависимости от того, является ли это работает система, таблица индексации и т.д. Если у вас есть больше требований просто добавить к комментариям, и я буду добавлять в лучшее установленный ответ.

* также, не могли бы вы завести это для нас: ПОКАЗАТЬ СОЗДАТЬ ТАБЛИЦУ tableA; то мы можем правильно использовать индексирование.

+0

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

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