【问题标题】:MySQL: duplicate entry error with SELECT...INSERT INTO with UNIQUE constraintMySQL:使用 SELECT...INSERT INTO 与 UNIQUE 约束重复输入错误
【发布时间】:2010-10-28 04:14:31
【问题描述】:

我有下表:

CREATE TABLE `products_quantity` (
  `id` int(11) NOT NULL auto_increment,
  `product_id` varchar(100) NOT NULL,
  `stock_id` int(11) NOT NULL,
  `quantity` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `product_id` (`product_id`,`stock_id`),
  KEY `products_quantity_product_id` (`product_id`),
  KEY `products_quantity_stock_id` (`stock_id`)
) ENGINE=MyISAM

product_id 是另一个表的外键,stock_id 也是。

该表目前有 10 000 多行,所有行都具有相同的 stock_id (1)。我想要做的是将其所有行复制两次,两次都使用新的 stock_id(2 和 3),以及 'quantity' 的随机值。

这是 SQL:

INSERT INTO `products_quantity` (product_id, stock_id, quantity)
    SELECT product_id, 2 AS stock_id, FLOOR(-1 + (RAND() * 15)) AS random_quantity FROM products_quantity;

效果很好。它使用另一个 stock_id 创建 10 000 多个新行,因此尽管每行的 product_id 已经存在,但不会违反唯一性约束。

此时表中的行示例,按 product_id 排序(一个 VARCHAR,丑陋但必要),请原谅格式:

22      0032705090062   1   1
10783   0032705090062   2   13
21      0032705090345   1   6
10784   0032705090345   2   0
...

每个 product_id 两次,每个 stock_id 一次。现在,如果我想以类似的方式创建第三个库存,使用与上次完全相同的查询但替换为“3 AS stock_id”,我会在第一个产品行中收到此错误:

“密钥 2 的重复条目 '0032705090062-3'”

尽管 product_id 0032705090062 和 stock_id 3 的组合与 stock_id 1 和 2 的组合一样唯一,但据说违反了唯一性约束,不是吗?

有趣的是,单行被创建,所以有一个新行:

21563    0032705090062  3   5

...但这是我尝试插入的 10 000 多个中唯一的一个。

我在这里缺少什么?为什么第一个 SELECT...INSERT INTO 有效,而第二个无效?

【问题讨论】:

    标签: mysql select insert duplicates


    【解决方案1】:

    你是从你插入的同一个表中选择的,所以它第一次抓取

    22      0032705090062   1       1
    21      0032705090345   1       6
    

    然后插入

    10783   0032705090062   2       13
    10784   0032705090345   2       0
    

    但是当你再次运行它时,它会:

    GET     22      0032705090062   1       1
    INSERT  21563   0032705090062   3       5
    GET     10783   0032705090062   2       13
    INSERT          0032705090062   3   <-- oops, already exists
    

    您只需将WHERE stock_id = 1 添加到您的SELECT 中

    【讨论】:

    • 非常感谢!我没有意识到这一点。现在可以使用了。
    【解决方案2】:

    简单:

    INSERT INTO `products_quantity` (product_id, stock_id, quantity)
        SELECT 
          product_id, 
          3 AS stock_id, 
          FLOOR(-1 + (RAND() * 15)) AS random_quantity 
        FROM 
          products_quantity;
        WHERE
          stock_id = 1  /* !!!!! */
    

    您的第二次插入失败,因为现在有 20.000 行(不是 10.000,就像您想象的那样)。添加 where 子句可确保仅插入 10.000 个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-15
      • 2014-03-22
      • 2012-01-23
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-25
      相关资源
      最近更新 更多