如何使用ON DUPLICATE KEY INSERT INTO ... SELECT

时间:2013-02-05 05:18:25

标签: mysql insert-into on-duplicate-key select-into

我有两张结构相同的桌子。表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。所以MySQL摇摇晃晃地告诉我,我有一个Duplicate entry '8577' for key 'PRIMARY'

所以我多次尝试过去:

首先,我尝试选择要插入的各个列,将ad_id设置为NULL:

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

这适用于一行,然后再次导致重复的条目(因为@max是一个静态变量)。

我在这里做错了什么?我这样做太难了吗?

2 个答案:

答案 0 :(得分:1)

在你的情况下为什么不使用?

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

答案 1 :(得分:0)

您可以删除ad_id table 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

然后尝试你常用的查询,即

ad_id

更新1

如果您不想拥有多个 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); ,那么您可以直接尝试此查询

{{1}}

以下是SQL Fiddle