Подтвердить что ты не робот

Поиск следующего доступного id в MySQL

Мне нужно найти следующий доступный идентификатор (если в базе данных есть 5 данных, я должен получить следующее доступное место вставки, которое равно 6) в базе данных MySQL. Как я могу это сделать? Я использовал MAX(id), но когда я удаляю несколько строк из базы данных, он по-прежнему сохраняет старое максимальное значение, которое оно не обновляло.

4b9b3361

Ответ 1

Я не думаю, что вы можете быть уверены в id next, потому что кто-то может вставить новую строку сразу после того, как вы попросите следующий идентификатор. Вам, по крайней мере, потребуется транзакция, и если я не ошибаюсь, вы можете получить только фактический идентификатор, используемый после, по крайней мере, это обычный способ его обработки - см. http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html

Ответ 2

Обновление 2014-12-05: Я не рекомендую этот подход по причинам, изложенным в ответе Саймона (принято), а также в комментарии Диего. Пожалуйста, используйте запрос ниже на свой страх и риск.

Самый короткий, который я нашел на сайте разработчика mysql:

SELECT Auto_increment FROM information_schema.tables WHERE table_name='the_table_you_want'

помните, если у вас мало баз данных с одинаковыми таблицами, вы также должны указать имя базы данных, например:

SELECT Auto_increment FROM information_schema.tables WHERE table_name='the_table_you_want' AND table_schema='the_database_you_want';

Ответ 3

В дополнение к Lukasz Lysik ответ - LEFT-JOIN тип SQL.
Как я понимаю, если есть id: 1,2,4,5, он должен вернуть 3.

SELECT u.Id + 1 AS FirstAvailableId
FROM users u
LEFT JOIN users u1 ON u1.Id = u.Id + 1
WHERE u1.Id IS NULL
ORDER BY u.Id
LIMIT 0, 1

Надеюсь, это поможет некоторым посетителям, хотя почта довольно старая.

Ответ 4

Учитывая то, что вы сказали в комментарии:

my id coloumn - это автоматический инкремент, я должен получить идентификатор и преобразовать его в другую базу. Поэтому мне нужно получить следующий идентификатор до того, как будет вставлен код причины, в который будет вставлен преобразованный код.

Существует способ сделать то, что вы просите, а именно: спросить таблицу, что следующий вставленный идентификатор строки будет, прежде чем вы вставляете:

SHOW TABLE STATUS WHERE name = "myTable"

в этом результирующем наборе появится поле "Auto_increment", в котором указывается следующее значение автоматического прироста.

Ответ 5

Как я понимаю, если есть id: 1,2,4,5, он должен вернуть 3.

SELECT t1.id + 1
FROM theTable t1
WHERE NOT EXISTS (
    SELECT * 
    FROM theTable t2
    WHERE t2.id = t1.id + 1
)
LIMIT 1

Ответ 6

ты сказал:

my id coloumn - это автоматический инкремент, который у меня есть получить идентификатор и преобразовать его в другая база. Поэтому мне нужно получить следующий id перед вставкой вызвать преобразованный код также будет вставлен.

то, что вы просите, очень опасно и приведет к состоянию гонки. если ваш код запускается дважды в то же время разными пользователями, они оба получат 6, а их обновления или вставки будут перешагиваться друг на друга.

Я предлагаю вам вместо INSERT в таблицу получить значение auto_increment с помощью LAST_INSERT_ID(), а затем UPDATE строку для установки любого значения, которое у вас есть, которое зависит от значения auto_increment.

Ответ 7

Если вы хотите выбрать первый пробел, используйте это:

SELECT  @r
FROM    (
        SELECT  @r := MIN(id) - 1
        FROM    t_source2
        ) vars,
        t_source2
WHERE   (@r := @r + 1) <> id
ORDER BY
        id
LIMIT   1;

Существует синтаксическая версия ANSI того же запроса:

SELECT  id
FROM    mytable mo
WHERE   (
        SELECT  id + 1
        FROM    mytable mi
        WHERE   mi.id < mo.id
        ORDER BY
                mi.id DESC
        LIMIT 1
        ) <> id
ORDER BY
        id,
LIMIT   1

однако он будет медленным из-за ошибки оптимизатора в MySQL.

Ответ 8

Если вы действительно хотите вычислить ключ следующей вставки перед вставкой строки (что, на мой взгляд, не очень хорошая идея), то я бы предложил использовать максимальный текущий id плюс один:

SELECT MAX(id) + 1 FROM table

Но я бы предположил, что вы позволили MySQL создать сам идентификатор (используя столбец с автоматическим увеличением) и используя LAST_INSERT_ID(), чтобы получить его из СУБД. Для этого используйте транзакцию, в которой вы выполняете вставку, а затем запрашиваете идентификатор, например:

INSERT INTO table (col1) VALUES ("Text");
SELECT LAST_INSERT_ID();

Теперь возвращаемое число содержит только один столбец, который содержит идентификатор вновь созданной строки.

Ответ 9

Один из способов сделать это - автоматическое увеличение индекса. Тогда ваш оператор SQL просто указывает NULL, а затем синтаксический анализатор SQL делает все остальное для вас.

INSERT INTO foo VALUES (null);

Ответ 10

Если это используется совместно для ВСТАВКИ новой записи, вы можете использовать что-то вроде этого.

(Вы указали в своих комментариях, что идентификатор автоматически увеличивается, а другой таблице нужен следующий идентификатор + 1)

INSERT INTO TABLE2 (id, field1, field2, field3, etc) 
VALUES(
   SELECT (MAX(id) + 1), field1, field2, field3, etc FROM TABLE1
   WHERE condition_here_if_needed
)

Это псевдокод, но вы получаете идею

Ответ 11

Слишком поздно ответить на этот вопрос сейчас, но надеюсь, что это поможет кому-то.

@Eimantas уже дал лучший ответ, но решение не будет работать, если у вас есть две или более таблицы под тем же именем под одним и тем же сервером.

У меня есть слегка измененный ответ @Eimantas для решения вышеуказанной проблемы.

select Auto_increment as id from information_schema.tables where table_name = 'table_name' and table_schema = 'database_name'

Ответ 12

Проблема со многими решениями заключается в том, что они только находят следующий "GAP", игнорируя, если "1" доступно, или если нет каких-либо строк, они возвратят NULL в качестве следующего "GAP".

Следующее будет не только найти следующий доступный пробел, но также учитывать, если первый доступный номер равен 1:

SELECT CASE WHEN MIN(MyID) IS NULL OR MIN(MyID)>1
-- return 1 if it available or if there are no rows yet
THEN
    1
ELSE -- find next gap
    (SELECT MIN(t.MyID)+1
    FROM MyTable t (updlock)
    WHERE NOT EXISTS (SELECT NULL FROM MyTable n WHERE n.MyID=t.MyID+1))
END AS NextID
FROM MyTable

Ответ 13

Это сработало для меня (MySQL 5.5), а также решило проблему "стартовой" позиции.

SELECT
    IF(res.nextID, res.nextID, @r) AS nextID
FROM
    (SELECT @r := 30) AS vars,
    (
    SELECT MIN(t1.id + 1) AS nextID
    FROM test t1
    LEFT JOIN test t2
      ON t1.id + 1 = t2.id
    WHERE t1.id >= @r
      AND t2.id IS NULL
      AND EXISTS (
          SELECT id
          FROM test
          WHERE id = @r
      )
  LIMIT 1
  ) AS res
LIMIT 1

Как упоминалось ранее, эти типы запросов очень медленные, по крайней мере, в MySQL.

Ответ 14

SELECT ID+1 "NEXTID" 
FROM ( 
    SELECT ID from TABLE1 
    WHERE ID>100 order by ID
) "X" 
WHERE not exists (
    SELECT 1 FROM TABLE1 t2
    WHERE t2.ID=X.ID+1
) 
LIMIT 1

Ответ 15

<?php
Class Database{
    public $db;
    public $host   = DB_HOST;
    public $user   = DB_USER;
    public $pass   = DB_PASS;
    public $dbname = DB_NAME;

    public $link;
    public $error;

    public function __construct(){
        $this->connectDB();
    }
    private function connectDB(){
    $this->link = new mysqli($this->host, $this->user, $this->pass, $this->dbname);
    if(!$this->link){
        $this->error ="Connection fail".$this->link->connect_error;
        return false;
    }
 }

    // Select or Read data

    public function select($query){
        $result = $this->link->query($query) or die($this->link->error.__LINE__);
        if($result->num_rows > 0){
            return $result;
        } else {
            return false;
        }
    }

}
 $db = new Database();
$query = "SELECT * FROM table_name WHERE id > '$current_postid' ORDER BY ID ASC LIMIT 1";
$postid = $db->select($query);
if ($postid) {
  while ($result = $postid->fetch_assoc()) { 
        echo $result['id'];
    } 

  } ?>