Проблема с 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                   |
+--------------+-----------------------+

Следующий запрос сделает это, но он будет работать, только если '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.

4 ответа

Решение

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

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

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

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

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

Это было сообщено как ошибка в MySQL.

Я цитирую Гилема Бичота:

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

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

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

Другие вопросы по тегам