Как удалить повторяющиеся строки в моей базе данных MySQL? (Оставьте тот, у которого самый низкий основной идентификатор)

Допустим, я хочу сначала выбрать строки, у которых одинаковая ссылка на загрузку. Затем я хочу сохранить тот, у которого самый низкий первичный идентификатор, и выбросить остальные.

Есть ли простой оператор SQL для этого? Будет ли это работать?

delete from mytable
where id not in
    (select min(id)
     from mytable
     group by download_link);

person TIMEX    schedule 02.11.2010    source источник
comment
Похоже, это должно сработать, у вас есть какая-то конкретная причина не просто попробовать?   -  person Wolph    schedule 02.11.2010
comment
В нем говорится следующее: ОШИБКА 1093 (HY000): вы не можете указать целевую таблицу «mytable» для обновления в предложении FROM.   -  person TIMEX    schedule 02.11.2010


Ответы (4)


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

DELETE t0
FROM mytable AS t0
JOIN mytable AS t1 ON t1.download_link=t0.download_link AND t1.id<t0.id;

То есть «удалить каждую строку, для которой есть другая строка с такой же ссылкой и меньшим идентификатором».

person bobince    schedule 02.11.2010

Что-то вроде этого должно работать:

DELETE FROM `table` 
WHERE `id` NOT IN (
    SELECT MIN(`id`) 
    FROM `table`
    GROUP BY `download_link`)

Чтобы быть в безопасности, перед запуском фактического запроса на удаление вы можете сделать эквивалентный выбор, чтобы увидеть, что удаляется:

SELECT * FROM `table` 
WHERE `id` NOT IN (
    SELECT MIN(`id`) 
    FROM `table`
    GROUP BY `download_link`)
person tdammers    schedule 02.11.2010
comment
В нем говорится следующее: ОШИБКА 1093 (HY000): вы не можете указать целевую таблицу «mytable» для обновления в предложении FROM. - person TIMEX; 02.11.2010
comment
Ах да, я тоже помню эту ошибку. Решил с помощью временной таблицы: CREATE TABLE #tmp (id int); ВСТАВИТЬ В #tmp SELECT MIN(id) FROM table GROUP BY download_link; УДАЛИТЬ ИЗ table ГДЕ НЕ id В (ВЫБРАТЬ id ИЗ #tmp); УДАЛИТЬ ТАБЛИЦУ #tmp; - person tdammers; 02.11.2010

Ошибка 1093 не позволяет вашему подходу работать в MySQL. Обходной путь путем создания временной таблицы:

  CREATE TEMPORARY TABLE table_purge SELECT MIN(id) id FROM table GROUP BY download_link;
  DELETE FROM table where id NOT IN (SELECT id FROM table_purge);

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

 DELETE table
  FROM table 
  NATURAL JOIN (
      SELECT id, download_link
      FROM table
      NATURAL JOIN (
          SELECT MIN(id) min_id, download_link
          FROM table
          GROUP BY download_link ) table_min
      WHERE id > min_id
  )  table_to_purge;
person hash1baby    schedule 02.11.2010

попробуйте следующий запрос

 delete from table where id not in 
 (select * from 
      (select min(id) from table group by download_link)
 SWA_TABAL)

Он отлично работает с mysql 5.0.x

person Romani    schedule 02.11.2010