mysql 下一个id_sql-在MySQL中查找下一个可用ID

当需要在MySQL数据库中找到下一个可用ID时,可以使用`information_schema.tables`表的`Auto_increment`字段来获取。例如,查询`SELECT Auto_increment FROM information_schema.tables WHERE table_name='your_table' AND table_schema='your_database'`可以得到下一个ID。然而,这种方法并不适用于并发情况,因为其他事务可能在查询后插入新的行。因此,使用事务和`LAST_INSERT_ID()`通常更安全。
摘要由CSDN通过智能技术生成

sql-在MySQL中查找下一个可用ID

我必须在MySQL数据库中找到下一个可用的id(如果数据库中有5个数据,我必须获取下一个可用的插入位置是6)。 我怎样才能做到这一点?我已经使用了MAX(id),但是当我从数据库中删除一些行时,它仍然保留了没有更新的旧最大值。

Burak Dede asked 2020-01-14T03:58:56Z

15个解决方案

85 votes

2014年12月5日更新:由于Simon(已接受)的回答以及Diego的评论中列出的原因,我不建议使用此方法。 请使用以下查询,后果自负。

我在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';

Eimantas answered 2020-01-14T03:59:34Z

21 votes

我认为您永远无法确定下一个ID,因为有人可能会在您要求下一个ID之后插入新行。 您至少需要一个事务,并且如果我没记错的话,您只能在插入事务后获得实际使用的ID,至少这是处理它的常用方法-参见[http://dev.mysql.com /doc/refman/5.0/en/getting-unique-id.html]

Simon Groenewolt answered 2020-01-14T03:59:05Z

17 votes

除了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

希望它能对一些访问者有所帮助,尽管帖子已经很老了。

Jarry answered 2020-01-14T04:00:03Z

12 votes

鉴于您在评论中所说的话:

我的id列是自动增量,我必须获取ID并将其转换为另一个base.So,我需要在插入之前获取下一个ID,因为也会插入转换后的代码。

有一种方法可以执行您要的操作,即在实际插入之前先询问表下一个插入的行的ID是什么:

SHOW TABLE STATUS WHERE name = "myTable"

该结果集中将存在一个名为“ Auto_increment”的字段,该字段会告诉您下一个自动增量值。

nickf answered 2020-01-14T04:00:37Z

10 votes

据我了解,如果具有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

Lukasz Lysik answered 2020-01-14T04:00:56Z

4 votes

你说:

我的ID栏是我有的自动递增   获取ID并将其转换为   另一个基地。所以我需要下一个   插入原因ID转换后的代码   也将被插入。

您要求的是非常危险的,并且会导致比赛状况。 如果您的代码由不同的用户在同一时间运行两次,那么他们两个都将获得6,并且他们的更新或插入操作将相互叠加。

我建议您改为将INSERT插入表中,使用LAST_INSERT_ID()获取auto_increment值,然后使用UPDATE该行设置取决于auto_increment值的任何值。

longneck answered 2020-01-14T04:01:30Z

3 votes

如果要选择第一个间隙,请使用以下方法:

SELECT @r

FROM (

SELECT @r := MIN(id) - 1

FROM t_source2

) vars,

t_source2

WHERE (@r := @r + 1) <> id

ORDER BY

id

LIMIT 1;

相同查询的语法版本为MySQL:

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中的优化程序错误,它会变慢。

Quassnoi answered 2020-01-14T04:01:59Z

1 votes

如果您真的想在插入行之前计算下一次插入的键(我认为这不是一个好主意),那么我建议您使用当前使用的最大id加一个:

SELECT MAX(id) + 1 FROM table

但是我建议您让MySQL自己创建id(通过使用自动增量列)并使用LAST_INSERT_ID()从DBMS中获取它。 为此,请使用一个事务,在该事务中执行插入,然后查询id,例如:

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

SELECT LAST_INSERT_ID();

现在,返回集仅包含一列,其中包含新生成的行的ID。

Xperimental answered 2020-01-14T04:02:28Z

1 votes

现在回答这个问题为时已晚,但是希望这对某人有所帮助。

@Eimantas已经给出了最佳答案,但是如果您在同一服务器上有两个或两个以上具有相同名称的表,则该解决方案将无法工作。

我对@Eimantas的答案做了些微修改,以解决上述问题。

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

Jay Bhatt answered 2020-01-14T04:02:57Z

0 votes

一种方法是将索引设置为自动递增。 然后,您的SQL语句仅指定NULL,然后SQL解析器为您完成其余的工作。

INSERT INTO foo VALUES (null);

gshauger answered 2020-01-14T04:03:17Z

0 votes

如果将其与插入新记录结合使用,则可以使用类似的内容。

(您已经在注释中指出ID是自动递增的,而另一个表则需要下一个ID + 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

)

这是伪代码,但您知道了

Phill Pafford answered 2020-01-14T04:03:46Z

-1 votes

许多解决方案的问题在于,它们仅找到下一个“ GAP”,而忽略“ 1”是否可用,或者如果没有任何行,则它们将返回NULL作为下一个“ GAP”。

以下内容不仅会找到下一个可用的间隔,还会考虑第一个可用的数字是否为1:

SELECT CASE WHEN MIN(MyID) IS NULL OR MIN(MyID)>1

-- return 1 if it's 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

Doug S answered 2020-01-14T04:04:10Z

-1 votes

这对我来说效果很好(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中是如此。

David H. answered 2020-01-14T04:04:35Z

-2 votes

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

ehuehu answered 2020-01-14T04:04:50Z

-2 votes

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'];

}

} ?>

Mahmudul Hasan answered 2020-01-14T04:05:06Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值