MySQL의 선택에서 삭제하는 방법은 무엇입니까?


87

이 코드는 MySQL 5.0에서 작동하지 않습니다. 작동하도록 다시 작성하는 방법

DELETE FROM posts where id=(SELECT id FROM posts GROUP BY id  HAVING ( COUNT(id) > 1 ))

고유 ID가없는 열을 삭제하고 싶습니다. 나는 대부분의 경우 유일한 ID를 추가 할 것입니다 (구문에서 시도했지만 잘 작동하지 않습니다).

답변:


214

SELECT(하위) 쿼리는 결과 집합을 반환 합니다 . 따라서 절이 IN아니라 를 사용해야 =합니다 WHERE.

또한 이 답변에 표시된 것처럼 동일한 쿼리 내의 하위 쿼리에서 동일한 테이블을 수정할 수 없습니다. 그러나 다음 중 하나를 수행 할 수 있습니다 SELECTDELETE별도의 쿼리, 또는 둥지 다른 하위 쿼리 및 별칭 내부 하위 쿼리 결과 (하지만, 외모 오히려 해키을)에서 :

DELETE FROM posts WHERE id IN (
    SELECT * FROM (
        SELECT id FROM posts GROUP BY id HAVING ( COUNT(id) > 1 )
    ) AS p
)

또는 Mchl이 제안한 조인 사용 하십시오 .


1
150 개의 중복 키가있는 테이블이 있습니다. 위의 쿼리를 실행했는데 "144 개의 행이 영향을 받음"이라고 말했지만 여전히 중복 키가 있습니다. 그래서 쿼리를 다시 실행했는데 5 개 행이 영향을 받았다고 다시 표시됩니다. 1 개 행이 영향을 받았습니다. 그런 다음 사라진 모든 중복 키. 왜 이런거야?
Alex

이것은 각 중복 세트 중 하나의 항목 만 삭제하기 때문에 발생합니다.SELECT id FROM posts GROUP BY id HAVING ( COUNT(id) > 1 )
havvg

# 1248 - 모든 테이블이 자신의 별명을 가지고 있어야 유도

@thang : 그래서 내부 하위 쿼리의 별칭을 지정했습니다.
BoltClock

1
"As p"가 무엇을하는지 설명해 주시겠습니까?
Cricketer

22
DELETE 
  p1
  FROM posts AS p1 
CROSS JOIN (
  SELECT ID FROM posts GROUP BY id HAVING COUNT(id) > 1
) AS p2
USING (id)

이것은 작동하는 것처럼 보이지만 구문이 혼란스럽고 다른 곳에서 설명 할 리소스를 찾을 수 없습니다. CROSS JOIN분명히 데카르트 조인을 수행하므로 불필요한 작업을 수행하거나 차선으로 수행 할 수 있습니까? 누구든지 설명 할 수 있습니까?
wintron 2014 년

USING절이 없는 경우에만 데카르트 곱을 수행합니다 . 하여 USING제품이 동일 값을 갖는 쌍에 한정되어 id열을하므로 실제로 매우 제한.
Mchl

내부 조인으로 동일한 작업을 수행 할 수 있습니까? IEDELETE p1 FROM posts AS p1 INNER JOIN ( SELECT ID FROM posts GROUP BY id HAVING COUNT(id) > 1 ) AS p2 ON p2.ID=p1.ID
Kodos Johnson

1
@ 앤드류 : 네. 기능적으로 이러한 조인은 정확히 동일합니다.
Mchl

5

내부 조인을 사용할 수 있습니다.

DELETE 
    ps 
FROM 
    posts ps INNER JOIN 
         (SELECT 
           distinct id 
         FROM 
             posts 
         GROUP BY id  
      HAVING COUNT(id) > 1 ) dubids on dubids.id = ps.id  

0

모든 중복 항목을 삭제하고 싶지만 각 중복 항목 중 하나를 삭제하려면 다음과 같은 해결책이 있습니다.

DELETE posts
FROM posts
LEFT JOIN (
    SELECT id
    FROM posts
    GROUP BY id
    HAVING COUNT(id) = 1

    UNION

    SELECT id
    FROM posts
    GROUP BY id
    HAVING COUNT(id) != 1
) AS duplicate USING (id)
WHERE duplicate.id IS NULL;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.