Проблема с MySql INSERT MAX() + 1

У меня есть одна таблица, содержащая много пользователей. В этой таблице у меня есть столбец с именем 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                   |
+--------------+-----------------------+

Следующий запрос будет делать это, но он будет работать, только если "Боб" уже существует в таблице...

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

Если Боб не существует (первая запись), user_id устанавливается в 0 (ноль). Это проблема. Мне нужно user_id, чтобы начать с 1 не 0.

Ответ 1

Вы можете использовать что-то вроде этого:

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

Но такой запрос может привести к состоянию гонки. Убедитесь, что вы находитесь в транзакции и блокируете таблицу пользователей перед ее запуском. В противном случае у вас могут быть два Боба с таким же числом.

Ответ 2

Вы можете использовать IFNULL:

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

Ответ 3

Он был как ошибка в MySQL.

Я цитирую Guilhem Bichot:

Во-вторых, вот простейший из обходных путей:
вместо использования:
вставить в значения foo (lfd) ((выберите max (lfd) из foo) +1)
просто делай вставить в foo (lfd) select (max (lfd) +1) из foo;

Ответ 4

Не используйте MAX() + 1, затем. Используйте схему автоматической нумерации в таблице.

Я не правильно прочитал вопрос. Используйте предложение Грега IFNULL().