Удалить дубликаты только с помощью запроса MySQL?

У меня есть таблица со следующими столбцами:

URL_ID    
URL_ADDR    
URL_Time

Я хочу удалить дубликаты на URL_ADDR столбец с помощью запроса MySQL.

Действительно ли возможно сделать такую вещь, не используя программирования?

14
задан p.campbell 1 August 2010 в 21:59
поделиться

6 ответов

Это будет работать при условии, что ваш столбец URL_ID уникален.

DELETE FROM url WHERE URL_ID IN (
SELECT URL_ID
FROM url a INNER JOIN (
    SELECT URL_ADDR, MAX(URL_ID) MaxURLId 
    FROM url
    GROUP BY URL_ADDR
    HAVING COUNT(*) > 1) b ON a.URL_ID <> b.MaxURLId AND a.URL_ADDR = b.URL_ADDR
)
0
ответ дан 1 December 2019 в 06:23
поделиться

В результате останутся те, у которых самый высокий URL_ID для конкретного URL_ADDR

DELETE FROM table
WHERE URL_ID NOT IN 
    (SELECT ID FROM 
       (SELECT MAX(URL_ID) AS ID 
        FROM table 
        WHERE URL_ID IS NOT NULL
        GROUP BY URL_ADDR ) X)   /*Sounds like you would need to GROUP BY a 
                                   calculated form - e.g. using REPLACE to 
                                  strip out www see Daniel's answer*/

(производная таблица 'X' нужна для того, чтобы избежать ошибки "You can't specify target table 'tablename' for update in FROM clause")

5
ответ дан 1 December 2019 в 06:23
поделиться

Ну, вы всегда могли:

  1. создать временную таблицу;
  2. INSERT INTO .... SELECT DISTINCT во временную таблицу из исходной таблицы;
  3. очистить исходную таблицу
  4. INSERT INTO ... SELECT в исходную таблицу из временной таблицы
  5. drop temp table.

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

3
ответ дан 1 December 2019 в 06:23
поделиться

Рассмотрим следующий тестовый случай:

CREATE TABLE mytb (url_id int, url_addr varchar(100));

INSERT INTO mytb VALUES (1, 'www.google.com');
INSERT INTO mytb VALUES (2, 'www.microsoft.com');
INSERT INTO mytb VALUES (3, 'www.apple.com');
INSERT INTO mytb VALUES (4, 'www.google.com');
INSERT INTO mytb VALUES (5, 'www.cnn.com');
INSERT INTO mytb VALUES (6, 'www.apple.com');

Где наша тестовая таблица теперь содержит:

SELECT * FROM mytb;
+--------+-------------------+
| url_id | url_addr          |
+--------+-------------------+
|      1 | www.google.com    |
|      2 | www.microsoft.com |
|      3 | www.apple.com     |
|      4 | www.google.com    |
|      5 | www.cnn.com       |
|      6 | www.apple.com     |
+--------+-------------------+
5 rows in set (0.00 sec)

Тогда мы можем использовать синтаксис multiple-table DELETE следующим образом:

DELETE t2
FROM   mytb t1
JOIN   mytb t2 ON (t2.url_addr = t1.url_addr AND t2.url_id > t1.url_id);

... который удалит дублирующие записи, оставив только первый url, основанный на url_id:

SELECT * FROM mytb;
+--------+-------------------+
| url_id | url_addr          |
+--------+-------------------+
|      1 | www.google.com    |
|      2 | www.microsoft.com |
|      3 | www.apple.com     |
|      5 | www.cnn.com       |
+--------+-------------------+
3 rows in set (0.00 sec)

UPDATE - В дополнение к новым комментариям выше:

Если дублирующие URL не будут иметь одинаковый формат, вы можете применить функцию REPLACE() для удаления www. или http:// частей. Например:

DELETE t2
FROM   mytb t1
JOIN   mytb t2 ON (REPLACE(t2.url_addr, 'www.', '') = 
                   REPLACE(t1.url_addr, 'www.', '') AND 
                   t2.url_id > t1.url_id);
31
ответ дан 1 December 2019 в 06:23
поделиться

Вы можете попробовать метод, упомянутый на http://labs.creativecommons.org/2010/01/12/removing-duplicate-rows-in-mysql/.

ALTER IGNORE TABLE your_table ADD UNIQUE INDEX `tmp_index` (URL_ADDR);
8
ответ дан 1 December 2019 в 06:23
поделиться

Вы можете сгруппировать по URL_ADDR, что даст вам только отдельные значения в поле URL_ADDR.

select 
 URL_ID
 URL_ADDR
 URL_Time
from
 some_table
group by
 URL_ADDR

Наслаждайтесь!

0
ответ дан 1 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: