【问题标题】:Problem with MySql INSERT MAX()+1MySql INSERT MAX()+1 的问题
【发布时间】:2010-12-07 22:29:34
【问题描述】:

我有一个包含许多用户的表。在该表中,我有一个名为 user_id (INT) 的列,我想为每个人分别递增。 user_id 必须从 1 开始

我准备了一个简单的例子:

Showing all names
+--------------+-----------------------+
| user_id      | name                  |
+--------------+-----------------------+
| 1            | Bob                   |
| 1            | Marry                 |
| 2            | Bob                   |
| 1            | John                  |
| 3            | Bob                   |
| 2            | Marry                 |
+--------------+-----------------------+


Showing only where name = Bob
+--------------+-----------------------+
| user_id      | name                  |
+--------------+-----------------------+
| 1            | Bob                   |
| 2            | Bob                   |
| 3            | Bob                   |
+--------------+-----------------------+

以下查询将执行此操作,但仅当表中已存在“Bob”时才有效...

INSERT INTO users(user_id, name) SELECT(SELECT MAX(user_id)+1 from users where 
name='Bob'), 'Bob';

如果 Bob 不存在(第一个条目),则 user_id 设置为 0(零)。这就是问题。我需要 user_id 从 1 而不是 0 开始。

【问题讨论】:

    标签: sql mysql insert max increment


    【解决方案1】:

    你可以这样使用:

    INSERT INTO users (user_id, name)
    SELECT 1 + coalesce((SELECT max(user_id) FROM users WHERE name='Bob'), 0), 'Bob';
    

    但是这样的查询可能会导致竞争条件。确保您处于事务中并在运行用户表之前锁定它。否则你可能会得到两个号码相同的 Bob。

    【讨论】:

    • 是的,查询有效,但请不要忽略第二部分。 :) 或者,如果您决定忽略它,至少在 (name, user_id) 上创建一个唯一索引,以便否则会产生重复的查询失败。
    • 这实际上是我的下一个问题,它在这里:stackoverflow.com/questions/1590648/…
    【解决方案2】:

    你可以使用IFNULL:

    INSERT INTO users(user_id, name)
    SELECT(IFNULL((SELECT MAX(user_id)+1 from users where name='Bob'), 1), 'Bob';
    

    【讨论】:

    • 看起来它可以工作,但由于某种原因mysql抛出一个语法错误:...syntax to use near 'SELECT MAX(user_id)+1 from users where name='Bob'),1) , 'Bob'' 在第 1 行
    • @Chad:将IFNULL( 替换为IFNULL(( 就可以了,只是括号不平衡。
    • 是的,这就是它不起作用的原因。我想知道哪种方法更快/最好。
    • 糟糕,修复了丢失的支架。我的答案和@Lukas 的答案几乎没有区别 - 使用您认为更容易阅读/理解的任何一个。
    【解决方案3】:

    reported as a bug in MySQL

    我在引用 Guilhem Bichot:

    其次,这是最简单的解决方法:
    而不是使用:
    插入 foo(lfd) 值((select max(lfd) from foo)+1)
    只是做
    插入 foo(lfd) select (max(lfd)+1) from foo;

    【讨论】:

      【解决方案4】:

      那么不要使用 MAX() + 1。在桌子上使用自动编号方案。

      我没有正确阅读问题。使用 Greg 对 IFNULL() 的建议。

      【讨论】:

      • 不会对每个记录按顺序对表编号进行自动编号方案,而不是使第一个“Bob”为 1,第二个“Bob”为 2,第一个“Chad”为 1,然后第二个“乍得”2等等?
      • 我没有正确阅读问题。我会用 IFNULL() 听从 Greg 的回答。
      猜你喜欢
      • 1970-01-01
      • 2010-11-26
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      相关资源
      最近更新 更多