【发布时间】:2013-10-29 10:39:59
【问题描述】:
我正在使用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 属性是used to generate a unique identity for new rows。
【问题讨论】:
-
不要为此使用 auto_increment。尽管有它的名字,但这不是它的用途。此外,除非在交易中绑定,否则您当前的解决方案受制于“竞争条件”。
-
不能用
IFNULL()处理子查询返回NULL的情况吗? -
@Strawberry,感谢您确认我关于 auto_increment 对这种情况没有用的评论。您能否详细说明您正在考虑的比赛条件?
-
@Barmar,听起来
IFNULL()是我需要的。当我能够返回这个项目(今天晚些时候)并在这里报告时,我会尝试一下。谢谢!
标签: mysql sql database mysql-5.1