0

次のクエリを実行しようとしています。

update list
set li = '6'
where li = '5'
and dn in ( SELECT dn FROM list GROUP BY dn HAVING COUNT(*) < 2000 )

このクエリを実行すると、上記のエラーが発生します。

You can't specify target table 'list' for update in FROM clause

そこで、次のように実行するようにアドバイスしてくれた人からアドバイスを受けました。

START TRANSACTION;
UPDATE  list a
    INNER JOIN
    (
        SELECT  dn 
        FROM    list 
        GROUP   BY dn 
        HAVING  COUNT(*) < 2000 
    ) b ON a.dn = b.dn
SET     a.li = '6'
WHERE   a.li = '5';

このコードは実行されます - 問題は決して終わらないことです。ステートメント自体に問題があるのか​​、それとも 400 万件のレコードが処理されているためなのかはわかりませんが、昨夜寝るときにそのままにしておいて、今朝はまだ終わっていませんでした。また、後付けとして、「START TRANSACTION;」をスローした場合に備えて、これをトランザクションにロールバックしようとしました。これの開始時に。

これはかなり一般的な質問だと思いますが、残念ながら、他の人のクエリを取得して自分のニーズに合わせて調整するほどSQLに精通していません。:p

これらのレコードを更新できるようにするソリューションを教えてくれる人はいますか? とても有難い。

4

3 に答える 3

2

これはうまくいくかもしれないので、上記の私のコメントから続けて、ここに答えがあります:

はい、'6' と '5' を囲む引用符を削除します。MySQL がli比較のたびに列を文字列にキャストするのは望ましくありません...そしてインデックスを作成します。

CREATE idx_dn_li ON list(dn, li);

UPDATE  list a
    INNER JOIN
    (
        SELECT  dn 
        FROM    list 
        GROUP   BY dn 
        HAVING  COUNT(*) < 2000 
    ) b ON a.dn = b.dn
SET     a.li = 6
WHERE   a.li = 5;

インデックスはあなたをGROUP BYより速くします、そしてそこにli列があることも役立つと思います(私が見たように、影響を受けるレコードがない場合、クエリはインデックスのみを読み取る必要がありますが、私の言葉を鵜呑みにしないでください)それ ;) )

于 2013-04-23T14:02:02.393 に答える
0

このエラーは、テーブルを更新しようとしていて、列を更新するために別のクエリで同じテーブルを使用している場合に生成されます。

同時に更新中のテーブルから選択することはできません。ただし、次のような複数テーブルの更新を行うことができます

UPDATE tbl AS a
  INNER JOIN tbl AS b ON ....
  SET a.col = b.col

または、クエリの簡略化されたバージョンを試してください

update list l1, ( SELECT dn FROM list GROUP BY dn HAVING COUNT(*) < 2000 ) AS l2
set li = '6'
where li = '5'
and dn = l2.dn

それが役立つことを願っています..これがあなたのためのリファレンスです... http://7php.com/mysql-update-select-statement-1093/

于 2013-04-23T12:47:07.793 に答える
0

クエリ:

update list
set li = '6'
where li = '5'
and dn in ( SELECT a.dn 
            FROM (SELECT * FROM list) a 
            GROUP BY a.dn 
            HAVING COUNT(*) < 2000 )

このクエリは、おそらくはるかに高速になります。

UPDATE list t
SET t.li = '6'
WHERE t.li = '5'
AND (SELECT COUNT(*)
     FROM (SELECT * FROM tik) a 
     WHERE a.dn = t.dn) < 2000
于 2013-04-23T12:50:45.353 に答える