MySQL: повторяющаяся ошибка ввода с SELECT ... INSERT INTO с уникальным ограничением - PullRequest
1 голос
/ 22 мая 2009

У меня есть следующая таблица:

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) и случайным значением для «количества».

Вот 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;

Это отлично работает. Он создает более 10 000 новых строк с другим stock_id, поэтому ограничение уникальности не нарушается, хотя 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', я получаю эту ошибку для самой первой строки продукта:

«Дублирующая запись« 0032705090062-3 »для ключа 2»

Внезапно ограничение уникальности предположительно нарушается, хотя комбинация product_id 0032705090062 и stock_id 3 так же уникальна, как и с stock_id 1 и 2, нет?

Как ни странно, единственная строка создана, поэтому появилась новая строка:

21563    0032705090062  3   5

... но это единственный из 10 000+, которые я пытаюсь вставить.

Что мне здесь не хватает? Почему первый SELECT ... INSERT INTO работает, а второй нет?

Ответы [ 2 ]

2 голосов
/ 22 мая 2009

Вы выбираете из той же таблицы, в которую вставляете, поэтому в первый раз она захватывает

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

1 голос
/ 22 мая 2009

Simple:

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.

...