2017-01-20 2 views
0

Dies ist meine Domains Tabelle:MySql entfernen Sie die Zeilen, die eine doppelte Spalte

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 
-------------|----------- 

Ich möchte die Zeilen löschen, wo sind doppelte Domains und halten den ersten Wert von ip, also muss ich eine haben Tabelle wie folgt schließlich:

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

Haben Sie schon etwas probiert? – GurV

+0

Ja. Ich habe eine neue Tabelle mit DISTINCT (Domäne) erstellt und danach versucht, ein PHP-Skript auszuführen, um für jeden dieser Werte die erste IP mit LIMIT 0,1 zu bekommen, aber das Skript braucht Jahre, da ich mehr als 400.000 Zeilen in der Datenbank habe . Ich bin kein Mysql-Experte – paulalexandru

+1

Dies ist ähnlich [diese Frage] (http://stackoverflow.com/questions/6103212/how-do-i-delete-duplicate-rows-and-keep-the-first-row) und andere auf StackOverflow –

Antwort

3

Versuchen INET_ATON und INET_NTOA mit GROUP BY mit mindestens IP für jede Domäne wie folgt zu erhalten:

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

MIN(IP) wird die Art und Weise arbeiten, die Sie erwarten würden.

Sie können einen Lösch unter Verwendung der oben wie folgt durchführen:

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; 

Bitte beachten Sie, dass, wenn mehrere Reihen mit mindestens IP für eine Domain sind, werden alle von ihnen gehalten werden.

Sie können alternativ eine neue Tabelle speichern unterschiedlichen Zeilen erstellen:

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

Diese Auswahl scheint gut zu sein. Die Sache ist, dass ich entweder den Rest der Zeilen entfernen möchte, oder diese Daten in eine separate identische Tabelle kopieren soll. – paulalexandru

+0

Die zweite Abfrage funktioniert nicht. Es löscht nicht genug Zeilen. Die Sache ist, dass die Auswahl funktioniert. – paulalexandru

+0

@paul funktioniert nicht wie? Ich habe es versucht und es löschte die Zeile 'example2.com | 9.9.9.9'.Wenn Sie über zwei Zeilen mit 'example3.com | sprechen 3.3.3.3' Werte, ich bereits erwähnt, dass in der Antwort, gibt es keine Möglichkeit, diese zu löschen, ohne eine temporäre Tabelle zu erstellen, laden bestimmte Daten in es, Tabelle löschen und zurückladen oder einfach wählen Sie verschiedene – GurV

0

So die dups zu löschen, Ihre Tabelle hat einen Primärschlüssel 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 aufgerufen vorausgesetzt
+0

Die Tabelle hat keine primäre ID, es ist genau so, wie Sie in der Frage sehen – paulalexandru

+0

Dann ist die Erstellung einer neuen Tabelle mit 'DISTINCT' wahrscheinlich Ihre beste Wette. – wogsland

0

die zweite Sammlung mit derselben Struktur erstellen und diese versuchen.

INSERT INTO second_table SELECT DISTINCT * FROM domains 
0

, wenn Sie jede Zeile eine eindeutige ID zuweisen

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

dann können Sie in der Lage sein, so etwas zu tun:

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); 

dann entfernen Sie die Schlüsselspalte

alter table domains drop column id; 
0

Dies sollte funktionieren:

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