0

我正在使用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 . 所以,如果插入三行,第一行是优先级 1,第二行是 2,第三行是 3。

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

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

我尝试将列转换为整数,但是当表中没有具有该客户 ID 的记录时,这仍然给了我 NULL。

在此示例中,我已经硬编码了客户 ID,但在我的应用程序中自然会成为输入参数。

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

有没有办法在一条 SQL 语句或少量 SQL 语句中做到这一点,即每行少于 SQL 语句?

我不认为我可以将优先级列设置为 auto_increment,因为该列不一定是唯一的,并且 auto_increment 属性用于为新行生成唯一标识

4

2 回答 2

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`
于 2013-10-29T10:50:47.407 回答
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
于 2013-10-29T10:58:53.353 回答