选择MySQL中的最后一行


182

如何SELECT在MySQL表中最后一行?

我正在INSERT读取数据,我需要从上一行中检索列值。

auto_increment桌子上有一个。


7
定义“最后一行”。ID最高的那个?还是最近添加的一个?
EboMike 2010年

1
什么表示最后一行-表格中是否有auto_increment或DATETIME列?
OMG小马

是的,里面有一个auto_increment。我想要最近添加的一个。
esqew

9
正如EboMike和OMG Ponies所说,一组中没有最后一行。如果我给你装满球的袋子,请你给我最后一个球,你会怎么办?
Vincent Savard

Answers:


400

是的,里面有一个auto_increment

如果您想要表中所有行的最后一行,那么最后MAX(id)就是正确答案的时候了!有点儿:

SELECT fields FROM table ORDER BY id DESC LIMIT 1;

12
恐怕如果需要对一百万行进行排序,速度会变慢,不是吗?
斯拉瓦

2
我刚刚运行了超过2000万行,而且速度非常快。我假设存在某种特殊情况来处理此查询。(编辑:MySQL 5.7,InnoDB引擎)
Daniel Buckmaster

1
@Pekka:我不想使用order by,还有其他选择吗?
湿婆

4
@Slawa否,如果id已索引。
罗恩侯爵,

31

请记住,关系数据库中的表只是行的集合。数学中的集合是无序集合。没有第一行或最后一行;没有上一行或下一行。

您必须首先按某个字段对一组无序行进行排序,然后才能按照定义的顺序释放结果集中的迭代。

由于您具有自动递增字段,因此我假设您希望将其作为排序字段。在这种情况下,您可能需要执行以下操作:

SELECT    *
FROM      your_table
ORDER BY  your_auto_increment_field DESC
LIMIT     1;

看看我们如何首先your_auto_increment_field按照降序(或您所称的名称)对无序行的集合进行排序。然后,将结果集限制为的第一行LIMIT 1


25

您可以将@spacepille建议的两个查询合并为一个看起来像这样的查询:

SELECT * FROM `table_name` WHERE id=(SELECT MAX(id) FROM `table_name`);

它应该工作得很快,但是在INNODB表上,它比ORDER + LIMIT慢了几分之一毫秒。


@karthikeyan在四天前写了他的答案,我在2015
。– vzr

不,我在4天前编辑并更正了一些拼写...发布日期是2014年,answered Jun 14 at 9:41多数民众赞成在大约1年零6个月之前:)
Dwza

只是为了清除空气,vzr是正确的。“ 6月14日”意味着2016年6月14日,@ karthikeyan也仅在这两个月成为会员。
罗伯特·布里斯塔

Ssooo ... @karthikeyan的答案是这个副本!
克里夫·伯顿

24

在具有很多行的表上,两个查询可能更快...

SELECT @last_id := MAX(id) FROM table;

SELECT * FROM table WHERE id = @last_id;


4

如果要添加最近的一个,请添加一个时间戳,然后选择按最高时间戳(限制1)的相反顺序排列。如果要按ID排序,请按ID排序。如果要使用您刚添加的那个,请使用mysql_insert_id


4

几乎每个数据库表都有一个auto_increment列(通常为id)

如果您想要表格中所有行的最后一行,

SELECT columns FROM table ORDER BY id DESC LIMIT 1;

要么

您可以将两个查询组合成一个看起来像这样的查询:

SELECT columns FROM table WHERE id=(SELECT MAX(id) FROM table);

仅当DBA(或创建该表的人)实施了自动递增时
才会存在


2

如果您有一个自动索引的列,那么这里的许多答案都说相同(按自动递增的顺序),这是可以的。

附带说明一下,如果您有这样的字段并且它主键,那么使用order byvs 不会对性能造成任何影响select max(id)。主键是如何在数据库文件中对数据进行排序(至少对于InnoDB是这样),RDBMS知道数据的结束位置,并且可以优化order by id + limit 1使其与到达数据库相同。max(id)

现在,当您没有自动递增的主键时,人迹罕至的地方。也许主键是一个自然键,它是3个字段的组合...但是,并不是全部都丢失了。从编程语言中,您可以首先获取行数

SELECT Count(*) - 1 AS rowcount FROM <yourTable>;

然后在LIMIT子句中使用获得的数字

SELECT * FROM orderbook2
LIMIT <number_from_rowcount>, 1

不幸的是,MySQL不允许在LIMIT子句中使用子查询或用户变量


1

您可以OFFSETLIMIT命令中使用:

SELECT * FROM aTable LIMIT 1 OFFSET 99

如果您的表有100行,则不依赖primary_key返回最后一行

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.