1

おおよそ次のようなデータがあります。

user_id   range   start   end
10        500     1       500
11        175
12        200

そしてそれを次のようなものに変換する必要があります:

user_id   range   start   end
10        500     1       500
11        175     501     675
12        200     676     875

したがって、後続の各行の開始番号は前の行の終了番号になります。現在の行の終了番号は、開始番号+範囲-1です。

私はこれを純粋にSQLで行おうとしていましたが、エラーが発生するため、少し行き詰まっているようです。

UPDATE  users U
SET     start = ( SELECT end+1 FROM users U2 WHERE U2.id = U.id - 1 )
WHERE   U.id > 1;

その結果、You can't specify target table 'users' for update in FROM clause-そして私がまだ解決策を探している間、解決策を見つけることができないようです。

4

2 に答える 2

1

テーブルが大きい場合はクエリが遅くなりますが、クロス結合を使用してこれを解決できる場合があります。

UPDATE users U CROSS JOIN users U2
SET U.start = U2.end WHERE U.id = U2.id - 1;

開始値に使用される終了値を含むレコードを参照する追加のフィールドを用意するというアイデアを検討するかもしれません。これにより、効率的な自己結合の更新が可能になり、自動インクリメントにギャップがある場合の問題が解決されます。クエリは次のようになります

UPDATE users U INNER JOIN users U2 on U.prev_id = U2.id
SET U.start = U2.end;
于 2012-09-14T16:24:22.270 に答える
1

この答えを見てください

基本的に、サブクエリ部分をサブクエリで変更します

(SELECT end+1 FROM (SELECT end, id FROM users) U2 WHERE U2.id = U.id - 1)

汚れていますが、動作するはずです。テーブルが大きい場合(およびmysqlサーバー上の他の構成値によっては)、地獄のように遅くなることに注意してください。これを本番コードで使用することはお勧めしません。また、後続のすべてのユーザーIDがあると想定していますが、そうではない場合があります。IDにギャップがある場合、フィールドにnullが設定されるか、失敗する可能性があります。

IDにギャップがある場合は、次のようにすることができます。

(SELECT end+1 FROM (SELECT end, id FROM users) U2 WHERE U2.id < U.id LIMIT 1)
于 2012-09-14T16:04:03.407 に答える