1

同じ構造のテーブルが 2 つあります。テーブル A には現在のすべての広告が含まれ、テーブル B にはアーカイブされた広告が含まれます。列 1 (ad_id) は主キー、AI、INT です。テーブル エンジンは MyISAM です。

特定の日付より前のすべてのテーブル A の広告をアーカイブのテーブル B にコピーする必要があります。私の目標は、ad_id を除くすべてのフィールドを複製し、ad_id を自動インクリメントすることです。これが私が試みたものです:

INSERT INTO B`(`ad_id`, `ad_advertiser`, `ad_ln`, `ad_expire`) 
    SELECT *
    FROM A
    WHERE YEAR( ad_expire ) <= 2012

テーブル B には何千もの広告があり、テーブル A は頻繁にフラッシュされるため、一意の ID フィールドの数値が小さくなり、テーブル B の ID と重複することがよくありますDuplicate entry '8577' for key 'PRIMARY'

だから私はそれを乗り越えるためにいくつかの試みをしました:

最初に、挿入する個々の列を選択して、ad_idNULLに設定しようとしました。

INSERT INTO B(`ad_id`, `ad_advertiser`, `ad_ln`, `ad_expire`) 
    SELECT (NULL, `ad_advertiser`, `ad_ln`, `ad_expire`)
    FROM A
    WHERE YEAR( ad_expire ) <= 2012 

#1241 - Operand should contain 1 column(s)ワイルドカード * セレクターを使用するとエラーが発生しますが、重複エラーが発生します。

次にSELECT LAST_INSERT_ID()、常に 0 を返す を試しました。

次に、 を使用していくつか試してみましたON DUPLICATE KEY UPDATEが、うまくいかないようです。

私は最高のIDを取得しようとしました:

SELECT @max := max(ad_id) FROM B;

INSERT INTO B`(`ad_id`, `ad_advertiser`, `ad_ln`, `ad_expire`) 
  SELECT *
  FROM A
  WHERE YEAR( ad_expire ) <= 2012

ON DUPLICATE KEY UPDATE ad_id = @max + 1

これは正確に 1 行で機能しますが、再びエントリが重複します (@max は静的変数であるため)。

ここで何が間違っていますか?私はこの道を難しくしすぎていますか?

4

2 に答える 2

1

あなたの場合、なぜ使用しないのですか?

INSERT INTO B(`ad_advertiser`, `ad_ln`, `ad_expire`) 
    SELECT (`ad_advertiser`, `ad_ln`, `ad_expire`)
    FROM A
    WHERE YEAR( ad_expire ) <= 2012 
于 2013-02-05T05:31:02.303 に答える
0

次のコマンドを使用して、主キー制約を削除できますad_idtable B

ALTER TABLE B DROP PRIMARY KEY

次に、通常のクエリを試してください

INSERT INTO B`(`ad_id`, `ad_advertiser`, `ad_ln`, `ad_expire`) 
    SELECT *
    FROM A
    WHERE YEAR( ad_expire ) <= 2012

更新 1

複数にしたくない場合はad_id、このクエリを直接試すことができます

   INSERT INTO `B`(`ad_id`, `ad_advertiser`, `ad_ln`, `ad_expire`) 
    SELECT *
    FROM A
    WHERE YEAR( ad_expire ) <= 2012
   ON DUPLICATE KEY UPDATE
    ad_advertiser = VALUES(ad_advertiser), 
    ad_ln = VALUES(ad_ln), 
    ad_expire = VALUES(ad_expire);

これがSQLフィドルです

于 2013-02-05T06:11:41.663 に答える