>

아래 테이블이 있는데 이제는 "refIDs"가 중복 된 행을 삭제해야하지만 해당 참조가있는 행이 하나 이상 있어야합니다. 예를 들어 4 행과 5 행을 제거해야합니다. >

+----+-------+--------+--+
| ID | refID |  data  |  |
+----+-------+--------+--+
|  1 |  1023 | aaaaaa |  |
|  2 |  1024 | bbbbbb |  |
|  3 |  1025 | cccccc |  |
|  4 |  1023 | ffffff |  |
|  5 |  1023 | gggggg |  |
|  6 |  1022 | rrrrrr |  |
+----+-------+--------+--+


  • 답변 # 1

    이것은 Gordon Linoff의 쿼리와 비슷하지만 하위 쿼리는 없습니다 :

    DELETE t1 FROM table t1
      JOIN table t2
      ON t2.refID = t1.refID
      AND t2.ID < t1.ID
    
    

    내부 조인을 사용하여 refID는 같지만 ID는 낮은 다른 행이있는 행만 삭제합니다.

    하위 쿼리를 피하는 이점은 검색에 인덱스를 활용할 수 있다는 것입니다. 이 쿼리는 refID + ID의 여러 열 색인에서 잘 수행됩니다.

  • 답변 # 2

    할 것 :

    delete from t where 
    ID not in (select min(ID) from table t group by refID having count(*) > 1)
    and refID in (select refID from table t group by refID  having count(*) > 1)
    
    

    기준은 refId가 중복 항목이며 ID가 중복 항목의 최소 (id)와 다릅니다. refId가 색인되면 더 잘 작동합니다

    그렇지 않으면 아무것도 삭제하지 않을 때까지 다음 쿼리를 여러 번 발행 할 수 있습니다

    delete from t 
    where 
    ID in (select max(ID) from table t group by refID  having count(*) > 1)
    
    

  • 답변 # 3

    MySQL에서는 join 를 사용하여이 작업을 수행 할 수 있습니다  와이즈 비즈 :

    delete
    
    

    delete t from table t left join (select min(id) as id from table t group by refId ) tokeep on t.id = tokeep.id where tokeep.id is null; 마다 하위 쿼리는 RefId 의 최소값을 계산합니다.  열 (전체 테이블에서 고유 한 것으로 가정). 그것은 id 를 사용합니다  일치하지 않기 때문에 left join 가 있습니다.   NULL 의 가치 . 이들은 삭제 된 것들입니다.

  • 답변 # 4

    일부 경우에 Marcus와 NJ73의 답변보다 약간 더 빠른 일부 변형이 있습니다 :

    tokeep.id
    
    

    다른 사람에게 도움이되기를 바랍니다. 큰 테이블에서 마커스는 대답을 멈춘다. DELETE ourTable FROM ourTable JOIN (SELECT ID,targetField FROM ourTable GROUP BY targetField HAVING COUNT(*) > 1) t2 ON ourTable.targetField = t2.targetField AND ourTable.ID != t2.ID;

관련 자료

  • 이전 Oracle은 CLOB 내부의 문자열을 값으로 sql로 바꿉니다
  • 다음 javascript - 선택 상자를 선택한 후 SQL 데이터를로드 하시겠습니까?