Очистка идентичных строк с помощью SQL - PullRequest
3 голосов
/ 13 сентября 2009

Как очистить базу данных от идентичных по определенным строкам полей, чтобы там оставалась только одна копия каждого набора идентичных строк?

У меня есть таблица:

    CREATE TABLE table1 (field1 varchar(255), field2 varchar(255));

Я хотел бы очистить table1 от любых ненужных копий строк, оставив случайную строку из каждого набора строк с одинаковыми field1.

UPD : Пожалуйста, отправьте MySQL-совместимые команды.

Ответы [ 6 ]

4 голосов
/ 13 сентября 2009

Самый простой способ - использовать специфическую для MySQL команду ALTER IGNORE . Удалить строки, создав индекс, нецелесообразно, но работает очень хорошо. Ключевое слово IGNORE означает, что при создании индекса все повторяющиеся строки будут удалены. И, оставив индекс, который мы создадим ниже, предотвратит любые будущие дубликаты. Если вы не хотите такого поведения, просто удалите индекс после его создания.

ALTER IGNORE TABLE table1 ADD UNIQUE INDEX indexname (field1, field2)
1 голос
/ 13 сентября 2009

Отработав ответ Фрагсворта, я бы:

  1. Создать новую таблицу: NEW_TABLE
  2. Определите field1 в качестве первичного ключа
  3. Вставить строки в NEW_TABLE из старой таблицы
  4. Брось старый стол
  5. Переименуйте NEW_TABLE во что бы то ни было называли старую таблицу

Первичный ключ остановит вставку строк с одинаковым значением field1 и будет лучше в целом для последующих запросов.

1 голос
/ 13 сентября 2009

В MySQL:

CREATE TABLE `new_table` LIKE `table1`;
INSERT INTO `new_table` ( SELECT * FROM `table1` GROUP BY field1 );
DROP TABLE `table1`;
RENAME TABLE `new_table` TO `table1`;

Это точно не выберет «случайную» повторяющуюся строку, но может выполнить то, что вы хотите, если вас это не волнует.

Если у вас есть больше полей, которые должны быть уникальными в сочетании с остальными, добавьте их в предложение GROUP BY.

РЕДАКТИРОВАТЬ : Возврат к старому ответу

0 голосов
/ 13 сентября 2009

Для этого вы можете использовать синтаксис MYSQL ALTER IGNORE . Следующая команда удалит все дубликаты и оставит случайную строку:

alter ignore table table1 add unique index index1 (field1);

Было бы разумно сохранить индекс на месте, поэтому новые дубликаты не могут быть добавлены. Но если вы хотите, вы можете удалить индекс с помощью:

alter table table1 drop index index1;
0 голосов
/ 13 сентября 2009

Создайте новую таблицу ИЛИ добавьте уникальный ключ, самостоятельно присоединитесь и удалите все, кроме минимального ключа


Новая таблица:

Так что вы могли бы сделать новый стол без дупле. Я полагаю, вы уже подумали об этом.

 CREATE TABLE new_test (field1 INTEGER, field2 INTEGER);
    INSERT INTO new_test(field1,field2) SELECT DISTINCT field1,field2 FROM test;
    DROP TABLE test;
    RENAME TABLE new_test test;

Если бы у вас был уникальный ключ, вы могли бы самостоятельно объединиться и идентифицировать цели, имея уникальный ключ >, чем минимум. Если у вас не было такого ключа, вы могли бы сделать его:

Создать уникальный ключ:

ALTER TABLE t2 ADD COLUMN (pk INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY(pk));

В любом случае, теперь вы можете самостоятельно объединиться и сохранить МИНУТУ (pk):

Самостоятельное присоединение и удаление дубликатов:

mysql> DELETE dups.* FROM t2 AS dups
           INNER JOIN (
               SELECT field1,field2,MIN(pk) as MPK FROM t2
               GROUP BY field1,field2 HAVING COUNT(*) > 1 ) AS keep
           ON keep.field1=dups.field1
              AND keep.field2=dups.field2
              AND keep.MPK <> dups.pk;
0 голосов
/ 13 сентября 2009

Это должно сделать это (не проверено в SQL Server):

SELECT field1, field2
INTO #temp
FROM 
   (SELECT ROW_NUMBER() OVER (PARTITION BY field1 ORDER BY NEWID()) AS __ROW, *
    FROM table1) x
WHERE x.__ROW = 1;

DELETE table1;

INSERT table1 
SELECT field1, field2
FROM #temp;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...