如何使用INSERT ... SELECT与特定列自动递增,从1开始?

时间:2013-10-29 10:40:00

标签: mysql sql database mysql-5.1

我正在使用INSERT ... SELECT将特定列中的数据从视图插入到表中。这是目标表:

CREATE TABLE IF NOT EXISTS `queue` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `customerId` int(11) NOT NULL,
  `productId` int(11) NOT NULL,
  `priority` int(11) NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `customerId` (`customerId`),
  KEY `productId` (`productId`),
  KEY `priority` (`priority`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;

INSERT ... SELECT SQL我有工作,但我想尽可能改进它,如下所示:我希望插入的行在优先级列中以1开头,并且每个后续行都要增加优先级因此,如果插入了三行,则第一行为优先级1,第二行为2,第三行为。

“从1开始”规则的例外:如果目标表中存在指定客户的现有行,我希望插入的行以MAX(priority)+1为该客户开头。

我以为我可以使用子查询,但问题在于:有时子查询返回NULL(当指定客户的queue表中没有记录时),这会打破插入,因为{{ 1}}列不允许空值。

我尝试将列CAST为一个整数,但是当表中没有带有该客户ID的记录时,仍然会返回NULL。

我在这个例子中硬编码了客户ID,但在我的应用程序中自然是一个输入参数。

priority

有没有办法在一个SQL语句或少量SQL语句中执行此操作,即每行少于SQL语句?

我认为我不能将优先级列设置为auto_increment,因为此列不一定是唯一的,并且auto_increment属性为used to generate a unique identity for new rows

2 个答案:

答案 0 :(得分:0)

在评论中提及Barmar:使用IFNULL处理返回null的子查询。因此:

INSERT INTO `queue`
(
`customerId`,
`productId`,
`priority`,
`status`,
`orderId`)
SELECT
    123, -- This is the customer ID
    `PRODUCT_NO`,
    IFNULL((SELECT (MAX(`priority`)+1) FROM `queue` WHERE `customerId` = 123),1),
    'queued',
    null
FROM
    `queue_eligible_products_view`

答案 1 :(得分:0)

以下是如何进行递增:

INSERT INTO queue (customerId, productId, priority, status, orderId)
SELECT 123, product_no, @priority := @priority + 1, 'queued', null
FROM queue_eligible_products_view
JOIN (SELECT @priority := IFNULL(MAX(priority), 0)
      FROM queue
      WHERE customerId = 123) var