【问题标题】:How to use INSERT ... SELECT with a particular column auto-incrementing, starting at 1?如何使用 INSERT ... SELECT 与特定列自动递增,从 1 开始?
【发布时间】: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


【解决方案1】:

正如 Barmar 在 cmets 中提到的那样:使用 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`

【讨论】:

    【解决方案2】:

    以下是如何进行递增:

    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
    

    【讨论】:

      猜你喜欢
      • 2011-03-29
      • 2017-11-03
      • 2011-12-29
      • 2013-10-27
      • 2011-06-09
      • 2017-02-19
      • 2020-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多