2010-02-01 3 views
2

에 나는 내가 좋아하는 것이삭제 중복은 MySQL의

userid visitorid time 
1  10   2009-12-23 
1  18   2009-12-06 
1  18   2009-12-14 
1  18   2009-12-18 
1705 1678  2010-01-24 
1705 1699  2010-01-24 
1705 1700  2010-01-24 
1712 1   2010-01-25 
1712 640   2010-01-24 
1712 925   2010-01-25 
1712 1600  2010-01-24 
1712 1630  2010-01-25 
1712 1630  2010-01-24 
1713 1   2010-01-24 
1713 1   2010-01-23 

같은 테이블이 최신 하나를 제외한 모든 중복을 제거하도록 쿼리를 수행해야합니다. 아이디어가 있기를 바래요?

예, 테이블은 테이블을 가정이

userid visitorid time 
1  10   2009-12-23 
1  18   2009-12-18 
1705 1678  2010-01-24 
1705 1699  2010-01-24 
1705 1700  2010-01-24 
1712 1   2010-01-25 
1712 640   2010-01-24 
1712 925   2010-01-25 
1712 1600  2010-01-24 
1712 1630  2010-01-25 
1713 1   2010-01-24 

답변

4
Delete from YourTable VersionA 
    where VersionA.Time NOT IN 
    (select MAX(VersionB.Time) Time 
     from YourTable VersionB 
     where VersionA.UserID = VersionB.UserID 
      and VersionA.VisitorID = VersionB.VisitorID) 

구문, 조정해야 할 수도 있지만, 트릭을해야합니다. 또한 Subselect를 자체 테이블 FIRST에 사전 쿼리 한 다음 해당 결과 세트에 대해 DELETE FROM을 실행하려고 할 수 있습니다.

+0

# 1064 - SQL 구문에 오류가 있습니다. 'VersionA.Time NOT IN (MAX를 선택하십시오 (VersionB.Time) Time'at line 1 –

+0

근처에서 사용할 올바른 구문에 대한 MySQL 서버 버전에 해당하는 설명서를 확인하여 시간 필드를 무시하는 고유 한 행을 얻을 수 있습니까? 그런 다음 다른 모든 행을 삭제하고 최대 시간 필드를 사용 하시겠습니까? –

+0

"현재 테이블에서 삭제하고 하위 쿼리의 동일한 테이블에서 선택할 수 없습니다."http://dev.mysql.com/doc/refman/5.0 /en/delete.html - 테이블이 제대로 잠겨 있지 않고 아무도 아직 제대로 잠그지 않은 코드를 구현 한 사람이 없습니다. –

0

처럼해야 쿼리 한 후 호출 할 Visitors :

DELETE v1.* FROM Visitors v1 
LEFT JOIN (
    SELECT userid, visitorid, MAX(time) AS time 
    FROM Visitors v2 
    GROUP BY userid, visitorid 
) v3 ON v1.userid=v3.userid AND v1.visitorid=v3.visitorid AND v1.time = v3.time 
WHERE v3.userid IS NULL; 
0
DELETE mo.* 
FROM (
     SELECT userid, visitorid, MAX(time) AS mtime 
     FROM mytable 
     GROUP BY 
       userid, visitorid 
     ) mi 
JOIN mytable mo 
ON  mo.userid = mi.userid 
     AND mo.visitorid = mo.visitorid 
     AND mo.time < mi.mtime 
+0

감사하지만 이것은 하나만 제외하고 모든 행을 삭제합니다. 즉 각 사용자의 최신 행은 남습니다. –

0

당신은 이중 중첩 된 하위 쿼리와 함께, MySQL bug#6980를 해결해야합니다 당신이 원하는 가치를

DELETE FROM foo_table 
WHERE foo_table.time IN (
    SELECT time FROM (
     SELECT time FROM 
      foo_table 
      LEFT OUTER JOIN (
       SELECT MAX(time) AS time 
       FROM foo_table 
       GROUP BY userid, visitorid 
       ) AS foo_table_keep 
        USING (time) 
     WHERE 
      foo_table_keep.time IS NULL 
     ) AS foo_table_delete 
    ); 

GROUP BY가 단일 행에 이르기까지 중복 붕괴 사용하고, MAX(time)이 선택하는을. 원하는 경우 MAX 이외의 다른 집계 함수를 사용하십시오. 두 번 하위 쿼리를 포장 각 별칭을 제공

는 오류 방지 :

ERROR 1093 (HY000): You can't specify target table 'foo_table' for update in FROM clause 

를하고 문을 유지하기 위해 무엇을 선택하는 방법이 명확의 추가 장점이있다.