2017-01-20 2 views
0

Это мои домены таблица:MySql удалить строки, которые имеют столбец дубликата

domain  | ip 
-------------|----------- 
example.com | 0.0.0.0 
-------------|----------- 
example1.com | 1.1.1.1 
-------------|----------- 
example2.com | 2.2.2.2 
-------------|----------- 
example3.com | 3.3.3.3 
-------------|----------- 
example2.com | 9.9.9.9 
-------------|----------- 
example4.com | 4.4.4.4 
-------------|----------- 
example3.com | 3.3.3.3 
-------------|----------- 

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

domain  | ip 
-------------|----------- 
example.com | 0.0.0.0 
-------------|----------- 
example1.com | 1.1.1.1 
-------------|----------- 
example2.com | 2.2.2.2 
-------------|----------- 
example3.com | 3.3.3.3 
-------------|----------- 
example4.com | 4.4.4.4 
-------------|----------- 
+1

Вы еще что-нибудь пробовали? – GurV

+0

Да. Я создал новую таблицу с DISTINCT (доменом), и после этого я попытался запустить php-скрипт, чтобы получить для каждого из этого значения первый ip с LIMIT 0,1, но сценарий занимает много лет с тех пор, как у меня более 400 000 строк в базе данных , Я не эксперт mysql – paulalexandru

+1

Это похоже на [этот вопрос] (http://stackoverflow.com/questions/6103212/how-do-i-delete-duplicate-rows-and-keep-the-first-row) и другие в StackOverflow –

ответ

3

Попробуйте использовать INET_ATON и INET_NTOA с GROUP BY, чтобы получить наименьшую IP для каждого домена, как это:

SELECT 
    domain, INET_NTOA(MIN(INET_ATON(ip))) 
FROM 
    domains t1 
GROUP BY domain; 

MIN(IP) не будет работать так, как можно было бы ожидать.

Вы можете выполнить удаление с помощью выше, как это:

DELETE t1 FROM domains t1 
     INNER JOIN 
    (SELECT 
     domain, INET_NTOA(MIN(INET_ATON(ip))) ip 
    FROM 
     domains t1 
    GROUP BY domain) t2 ON t1.domain = t2.domain AND t1.ip <> t2.ip; 

Пожалуйста, обратите внимание, что если есть несколько строк с наименьшим IP для домена, все они будут сохранены.

Вы можете альтернативно создать новую таблицу для хранения различных строк:

CREATE TABLE domains_new(domain varchar(100), IP varchar(30)) 
SELECT 
    domain, INET_NTOA(MIN(INET_ATON(ip))) 
FROM 
    domains t1 
GROUP BY domain; 
+0

Этот выбор кажется хорошим. Дело в том, что я хочу либо удалить остальные строки, либо скопировать эти данные в отдельную идентичную таблицу. – paulalexandru

+0

Второй запрос не работает. Он не удаляет достаточно строк. Дело в том, что выбор работает. – paulalexandru

+0

@paul не работает как? Я пробовал это, и он удалил строку 'example2.com | 9.9.9.9'.Если вы говорите о двух строках с 'example3.com | 3.3.3.3', я уже упоминал, что в ответе нет способа удалить их, не создавая временную таблицу, загружая в нее отдельные данные, очищая таблицу и загружая обратно или просто выбирая выделенные – GurV

0

Так удалить Dups, предполагая, что ваша таблица имеет первичный ключ с именем id,

DELETE FROM domains 
WHERE id IN 
(SELECT dyt.id FROM domains oyt, domains dyt 
WHERE oyt.id < dyt.id 
AND oyt.domain = dyt.domain 
AND oyt.ip = dyt.ip) 
+0

В таблице нет первичного идентификатора, это точно так же, как вы видите в вопросе – paulalexandru

+0

. Тогда создание новой таблицы с использованием 'DISTINCT', вероятно, будет вашим лучшим выбором. – wogsland

0

создать вторую коллекцию с той же структурой и попробовать это.

INSERT INTO second_table SELECT DISTINCT * FROM domains 
0

если присвоить каждой строке уникальный идентификатор

alter table domains add column id int first; 
set @i = 0; 
update domains set id=(@i:[email protected]+1); 

, то вы можете быть в состоянии сделать что-то вроде этого:

delete from domains 
where id not in (select id from 
(select id, domain, ip from domains group by domain having count(domain) > 1) as subq); 

затем просто удалить ключевой столбец

alter table domains drop column id; 
0

Это должно работать:

WITH result AS (
    SELECT Domain, 
      Ip, 
      ROW_NUMBER() OVER (PARTITION BY p.Domain 
           ORDER BY p.Ip) AS rk 
     FROM DomainsTable p) 
SELECT r.Domain, r.Ip 
    FROM result r 
WHERE r.rk = 1 
Смежные вопросы