2017-01-20 3 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 
-------------|----------- 

내가 중복 된 도메인입니다 및 IP의 첫 번째 값을 유지 행을 삭제하려면, 그래서 나는이 있어야합니다 이 마지막으로 같은 테이블 :

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 (도메인)와 새로운 테이블을 만든 후 그 값의 각각에 대해 LIMIT 0,1과 첫 번째 IP를 얻으려고 PHP 스크립트를 실행하려했으나 데이터베이스에 400.000 개 이상의 행이 있기 때문에 스크립트는 수년이 걸린다. . 나는 mysql 전문가가 아니다 – paulalexandru

+1

이것은 [이 질문과 유사하다] (http://stackoverflow.com/questions/6103212/how-do-i-delete-duplicate-rows-and-keep-the-firstrow) 및 기타 StackOverflow에 –

답변

3

는 다음과 같이 각 도메인에 대해 최소한 IP를 얻을 수 GROUP BYINET_ATONINET_NTOA를 사용해보십시오 :

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

그래서 테이블이 id를라는 기본 키가 가정하고 DUPS을 삭제,

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

테이블에 기본 ID가 없으므로 질문에 표시된 것과 정확히 같습니다. – paulalexandru

+0

그러면 'DISTINCT'를 사용하여 새 테이블을 만드는 것이 가장 좋습니다. – wogsland

0

는 동일한 구조를 가진 두 번째 컬렉션을 만들이를 시도합니다.

INSERT INTO second_table SELECT DISTINCT * FROM domains 
0

각 행에 고유 ID를 할당하는 경우

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 
관련 문제