Удаление дубликатов определенного поля

#mysql #sql

#mysql #sql

Вопрос:

У меня таблица выглядит следующим образом:

 Field     | Type         | Null    | Key    | Default | Extra
---------- -------------- --------- -------- --------- ----------------
index     | int(11)      | NO      | PRI    | NULL    | auto_increment
itemid    | int(11)      | NO      |        | NULL    |
name      | varchar(32)  | NO      |        | NULL    |
meta      | int(11)      | NO      |        | NULL    |
  

Таблица маленькая, и мне не нужно заботиться об оптимизации.

Некоторые записи itemid , name и meta дублируются, но я хочу удалить все те, которые name дублировались, оставив одну запись (которая больше не дублируется.) Это MySQL. Я искал решение, но не нашел ничего, что могло бы удовлетворить мои потребности.

Комментарии:

1. индекс — это зарезервированное слово. Было бы лучше переименовать его, чтобы вам не приходилось использовать обратные ссылки каждый раз, когда вы его вызываете.

2. @nick rulez: и переписать код, который использует эту таблицу? 😉

3. Привет. изменить table tbl_name изменить index id int not null авто_инкремент;

4. @nick rulez: по какой причине? PK уже подразумевает, что поле является not null

5. Вы правы. Кажется, что достаточно изменить table tbl_name, изменить идентификатор индекса int auto_increment 🙂

Ответ №1:

Поскольку данных мало, могло бы быть проще создать таблицу с аналогичной структурой и выполнить такой запрос:

 INSERT INTO new_table (index, itemid, name, meta)
SELECT index, itemid, name, meta FROM old_table GROUP BY name
  

После этого удалите old_table и переименуйте new_table .

Также решением, которое могло бы сработать (я не уверен), было бы создание уникального индекса с IGNORE , например

 ALTER IGNORE TABLE tblname
ADD UNIQUE INDEX ix_name (name)
  

ИГНОРИРОВАТЬ — это расширение MySQL для стандартного SQL. Он контролирует, как работает ALTER TABLE, если в новой таблице есть дубликаты уникальных ключей или если при включении строгого режима появляются предупреждения. Если параметр ИГНОРИРОВАТЬ не указан, копирование прерывается и выполняется откат при возникновении ошибок с дублированием ключа. Если указано ИГНОРИРОВАТЬ, из строк с дубликатами по уникальному ключу используется только первая строка, остальные конфликтующие строки удаляются. Неправильные значения усекаются до наиболее близкого соответствия допустимому значению.

Комментарии:

1. Это было то, что я искал, если быть точным: CREATE TABLE itemstemp AS SELECT * FROM items GROUP BY name

2. @Sebi: да, удобное решение. Но также попробуйте добавить уникальный индекс, это помогло бы с меньшим количеством шагов.

Ответ №2:

Не уверен, что это то, что вы ищете, но вы могли бы попробовать предложение GROUP BY

 SELECT index, itemid, name, meta FROM table GROUP BY name