2013-07-19 20 views
8

で更新のためのターゲットテーブル 'NAME'を指定することはできません。this解を、重複しているMySQL DBのテーブルのデータに適用しようとしています。そのようなエラーが発生します。FROM句

SQL Error [1093] [HY000]: You can't specify target table 'NAME' for update in FROM clause 


DELETE NAME FROM NAME 
WHERE NAME.id NOT IN 
    (SELECT MIN(id) 
    FROM NAME GROUP BY col1, col2) 

また、エイリアスを割り当ててみましたが、成功しませんでした。 このエラーの原因は何ですか? これは一般的に、SQLスクリプトが周期的なプロセスを生成できることを指摘していますが、実際にはこれに関連することはありません - DELETESELECTの2つの選択が切り離されていることは明らかです - エンジンはSELECTを1回、 DELETEです。 なぜこのエラーが発生し、実際にテーブルを重複排除することができますか? =)

+1

クエリは、適用しようとしているソリューションのクエリとはまったく異なります。あなたは 'NOT IN'を使っているのに対し、彼らは結合を使用します。 – eggyal

+0

@eggyalコメントへの私のリンクは、回答ではなく、 –

+0

です。私はそれに気付かなかった。そのコメントは、SQL Server固有のものです。その答えで与えられた結合がMySQLで動作することがわかります。 – eggyal

答えて

27

あなたがテーブルの使用DELETE FROM tablenameからレコードを削除したい場合は、これはあなた

DELETE FROM NAME 
WHERE NAME.id NOT IN (
        SELECT * FROM ( 
            SELECT MIN(id) FROM NAME GROUP BY col1,col2 
            ) AS p 
        ) 

Read more

+0

@GillBates私の更新された回答を確認してください –

+0

ワウ - 非自明の解決策!出来た! –

+0

あなたが歓迎:)、それはあなたのために働いた素晴らしい! –

0

役立つかもしれないしてみてください。ここで列を指定することはできません。列からデータを削除する場合は、UPDATE文を使用して列の値を空白またはNULLに設定してください。

3

From the manual
"現在、テーブルから削除して、サブクエリ内の同じテーブルから選択することはできません。

適切なデータベースエンジンを使用するか、クエリを個別に実行します。 (間に、IDのプログラムで保存する。)

+0

あなたに例を挙げてもらえますか? – Tarik

+1

適切なデータベースのですか? PostgreSQL。 – aib

4

あなたのクエリが正確であるとの条件を満たしているすべてのデータを削除するので、削除

のsintaxが列

の名前を必要としません他のDBMSでも動作しますが、MySQLでは、テーブルの更新や削除、サブクエリ内の同じテーブルからの選択はできません。それは公式DELETEの文書に記載されています。

将来のリリースで修正される可能性がありますが、現在のところ、クエリはサポートされていません。

簡単な修正はecho_Meの答えのように、サブサブクエリであなたのサブクエリを置くために、次のようになります。

WHERE NAME.id NOT IN (SELECT * FROM (your subquery) s) 

これはあなたのサブクエリの結果を一時テーブルを作成するために、MySQLを強制し、あなた以来だろう実際には同じテーブルから選択するのではなく、一時テーブルからこのクエリが正常に実行されます。しかし、パフォーマンスは悪いかもしれません。

通常、ジョインを使用してエラー#1093を取り除きます。

DELETE NAME 
FROM 
    NAME LEFT JOIN (
    SELECT col1, col2, MIN(id) min_id 
    FROM NAME 
    GROUP BY col1, col2) s 
    ON (NAME.col1, NAME.col2, NAME.id) = (s.col1, s.col2, s.min_id) 
WHERE 
    s.min_id IS NULL 

またはあなたが最速のものでなければならない。この簡単なバージョンを、使用することができます:

DELETE N1 
FROM 
    NAME N1 INNER JOIN NAME N2 
    ON 
    N1.col1=N2.COL1 
    AND N1.col2=N2.col2 
    AND N1.ID > N2.ID 

フィドルはhereですこれは、フォームの参加で、あなたのクエリです。

関連する問題