我正在使用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。
答案 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