2010-12-30 6 views
61

このコードは、MySQL 5.0は動作しません、ためにどのようにそれはそれは私が一意のIDを持っていけない列を削除したいMySQLでselectから削除するには?

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

動作させるために再書き込み。私はそのほとんどの時間をその唯一のID(構文で試してみましたが、うまくいきません)と付け加えます。

答えて

144

SELECT(サブ)クエリは返信結果に設定します。したがって、WHERE句にはINを使用し、=を使用する必要はありません。

さらに、this answerに示すように、同じクエリ内のサブクエリから同じテーブルを変更することはできません。ただし、いずれかの別のクエリで、その後SELECTDELETE、または巣別のサブクエリとエイリアス内側のサブクエリの結果は(ただし、かなりハックに見える)ことができます。

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

または使用はas suggested by Mchlに参加します。

+1

私が持っていました150の重複キーを持つテーブル。私は上記のクエリを実行し、それは "影響を受ける144行"と述べたが、そこにはまだ重複するキーがある。だから私は再度クエリを実行し、それは5行影響を受けた、再び:1行が影響を受けると言います。その後、重複したキーはすべて消えてしまいます。どうしてこれなの?#1248 - すべての派生テーブルは、独自のエイリアスを持つ必要があります。 – Alex

+0

#1248 - すべての派生テーブルは、独自のエイリアスを持つ必要があります。 – thang

+0

@ thang:それで、私は内側のサブクエリのエイリアスを言ったのです。 – BoltClock

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

これは動作するようですが、構文では混乱していて、それを説明するために他の場所。 'CROSS JOIN'は明らかにデカルト結合を実行するので、これは不必要な作業を行うかもしれないか、または最適以下に実行するように思われるでしょうか?誰でも説明できますか? – wintron

+0

'USING'句がない場合にのみデカルト積を行います。 'USING'では、' id'カラムに同じ値を持つペアに限定されているので、実際は非常に限られています。 – Mchl

+1

恐ろしい解決策。 –

-1

あなたはすべての重複を削除したいのですが、重複の各セットのうち一つは、これは一つの解決策である場合:

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

あなたが内部使用することができますが参加:

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 
関連する問題