简体   繁体   English

从mysql获取最后一条记录

[英]Getting last record from mysql

I am using mysql and facing some problem. 我正在使用mysql并面临一些问题。 I want to retrieve last row that is inserted. 我想要检索插入的最后一行。

<< Below are details >> <<下面是详细信息>>

Below is how I created table. 以下是我创建表格的方法。

create table maxID (myID varchar(4))

I inserted four values in it as below 我在其中插入了四个值,如下所示

insert into maxID values ('A001')
insert into maxID values ('A002')
insert into maxID values ('A004')
insert into maxID values ('A003')

When I execute select myID, last_insert_id() as NewID from maxID , I get output as below 当我select myID, last_insert_id() as NewID from maxID执行select myID, last_insert_id() as NewID from maxID ,我得到如下输出

myId NewID
A001   0  
A002   0  
A004   0  
A003   0    

When I tried below code, 当我尝试下面的代码,

select myId, last_insert_id() as NewID, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init

I get output as below. 我得到如下输出。

myId NewID  rowid
A001   0      1
A002   0      2
A004   0      3
A003   0      4

However when I use code select myId, last_insert_id() as NewID, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init where @rowid = 4 , I get error as Uknown column 'myrow' in where clause 但是当我使用代码select myId, last_insert_id() as NewID, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init where @rowid = 4 ,我得到错误为Uknown column 'myrow' in where clause

When I use where @rowid=4 , I don't get any data in tables. 当我where @rowid=4使用时,我没有得到表格中的任何数据。

Link to play with data 链接播放数据

Note: Here I am using 4 just to get desired output. 注意:这里我使用4只是为了获得所需的输出。 Later I can get this from a query (select max(rowid) from maxID) 稍后我可以从查询中获取此信息(select max(rowid) from maxID)

Please suggest me what need to do if I want to see only last record ie A003 . 如果我只想查看最后一条记录,即A003请建议我需要做什么。

Thanks for your time. 谢谢你的时间。

Update: 更新:

I already have millions of data in my table so I can't add new column in it as suggested below. 我的表中已有数百万个数据,因此我无法在其中添加新列,如下所示。

Almost done. 几乎完成了。 You succeed in getting the insert order. 您成功获得了插入顺序。 So: 所以:

select myId, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init ORDER BY myrow desc LIMIT 1;

In my console I get the following: 在我的控制台中,我得到以下内容:

mysql> select myId, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as
init ORDER BY myrow desc LIMIT 1;
+------+-------+
| myId | myrow |
+------+-------+
| A003 |     4 |
+------+-------+
1 row in set (0.00 sec)

Demo 演示

UPDATE UPDATE

Yak is right. 牦牛是对的。 My solution is not deterministic. 我的解决方案不是确定性的。 Maybe it works for small amount of records. 也许它适用于少量记录。 I found tons of post abount unreliability of default sorting of a SELECT statement ( here for example ). 我发现大量的post abount不可靠的SELECT语句的默认排序( 例如这里 )。 Next steps: 下一步:

  • Under which conditions the default SELECT sorting matches the insertion order? 在哪些条件下,默认的SELECT排序与插入顺序匹配?
  • Is it possible to obtain the last inserted record in a table without an incremental id or an insertion timestamp? 是否可以在没有增量ID或插入时间戳的表中获取最后插入的记录?

I know it's not an answer, but stating the problem limit the problem. 我知道这不是答案,但说明问题会限制问题。

It seems that a SELECT is not guaranteed to return rows in any specific order (without using an ORDER BY clause, of course). 看来SELECT不能保证以任何特定顺序返回行(当然不使用ORDER BY子句)。

As per the SQL-92 standard (p. 373): 根据SQL-92标准 (p.373):

If an < order by clause > is not specified, then the table specified by the < cursor specification > is T and the ordering of rows in T is implementation-dependent. 如果未指定<order by clause>,则<cursor specification>指定的表为T,T中的行顺序与实现有关。

Okay, MySQL is not fully SQL-92-compliant, but this is a serious hint. 好的,MySQL并不完全符合SQL-92标准,但这是一个严肃的提示。

Laurynas Biveinis (apparently affiliated with Percona ) also states : Laurynas Biveinis(显然隶属于Percona也指出

The order of the rows in the absence of ORDER BY clause (...) could be different due to the moon phase and that is OK. 没有ORDER BY子句(...)的行的顺序可能因月相而不同,这是可以的。

The MySQL manual says about InnoDB: 关于InnoDB的MySQL手册说:

InnoDB always orders table rows according to [a PRIMARY KEY or NOT NULL UNIQUE index] if one is present. InnoDB总是根据[ PRIMARY KEYNOT NULL UNIQUE索引]对表行进行排序如果存在)。

As far as I am concerned, I assume MySQL could also reorder rows after an OPTIMIZE TABLE or even reuse empty spaces after many deletes and inserts (I have tried to find an example of this, and have failed so far). 就我而言,我假设 MySQL也可以在OPTIMIZE TABLE之后对行进行重新排序,甚至在许多删除和插入之后重复使用空格(我试图找到一个这样的例子 ,到目前为止都失败了)。

Given your table structure, the bottomline is, unfortunately, that so many factors could have altered the order of the rows; 鉴于您的表结构,不幸的是,底线是如此多的因素可能改变了行的顺序; I see no solution to reliably determine the order they were inserted. 我看不到可靠地确定插入顺序的解决方案。 Unless you kept all binary logs since you created the table, of course ;) 除非你创建表后保留所有二进制日志,当然;)

Nevertheless, you may still want to add a sequence column to your table. 不过,您可能仍希望在表中添加sequence列。 Existing rows would be assigned a possibly inaccurate sequence number, but at least future rows will be correctly sequenced. 将为现有行分配可能不准确的序列号,但至少将来的行将被正确排序。

ALTER TABLE maxID ADD sequence INT DEFAULT NULL;
ALTER TABLE maxID ADD INDEX(sequence);
ALTER TABLE maxID MODIFY sequence INT AUTO_INCREMENT;

http://sqlfiddle.com/#!2/63a8d/1 http://sqlfiddle.com/#!2/63a8d/1

From your insert script, A004 is not the last inserted record. 从插入脚本中, A004不是最后插入的记录。 It's the third one. 这是第三个。 If you want to get the last record in alphabetical order (which A004 is), you must use 如果A004字母顺序( A004是)获取最后一条记录,则必须使用

select myID from maxID order by myID desc limit 1

If you want the last inserted row, why don't you just use add an autoincrement column to your table? 如果您想要最后插入的行,为什么不使用向表中添加自动增量列? That's the point of those kinds of columns. 这就是那些列的重点。 The autoincrement column doesn't have to be the PK (it should be, but doesn't have to if you don't have the choice). 自动增量列不必是PK(它应该是,但如果您没有选择则不必)。

As mentioned in the MySQL help for last_insert_id , you can only use it with **auto-increment columns. 正如在last_insert_idMySQL帮助中所提到的,您只能将其与**自动增量列一起使用。 This means that you cannot make MySQL find the most recently inserted row for you, unless you know something about the order of the IDs. 这意味着您无法让MySQL找到最近插入的行,除非您了解ID的顺序。 If they are sorted like your example suggests, then you can use 如果按照您的示例建议对它们进行排序,则可以使用

SELECT *
FROM maxID
WHERE myId = max(myId)

But I suggest adding an auto-increment column to the table and then use = last_insert_id() in your WHERE clause. 但我建议在表中添加一个自动增量列 ,然后在WHERE子句中使用= last_insert_id() See also this page for information on how to obtain the last ID. 有关如何获取最后一个ID的信息,另请参阅此页面

last_insert_id does not work because it only returns the last value generated by an auto-increment field. last_insert_id不起作用,因为它只返回自动增量字段生成的最后一个值。 However I think that solution may be on the right track. 但是,我认为解决方案可能正在走上正轨。 I would suggest adding another column that is a auto-increment integer. 我建议添加另一个自动增量整数列。 You can then insert data and to retrieve the row you just inserted select the last_insert_id(). 然后,您可以插入数据并检索刚刚插入的行,选择last_insert_id()。 To retrieve the most recent row (inserted by any process) select the max number for the new column, or sort by it desc. 要检索最近的行(由任何进程插入),请选择新列的最大数量,或按其desc进行排序。

If you want to use the varchar column you can do an alphabetic sort, but that does not guarantee it will be the last row you inserted row or even the most recently inserted row. 如果要使用varchar列,可以进行字母排序,但这并不能保证它将是您插入行的最后一行,甚至是最近插入的行。

The one other solution I can think of which may do what you need is to create a stored procedure which creates the row, inserts it into the table, and then returns it to you. 我能想到的另一个解决方案可能就是创建一个存储过程,该行创建行,将其插入表中,然后将其返回给您。

Your usage of @rowid is simply counting the order rows are returned to you. 您对@rowid的使用只是计算返回给您的订单行。 There is no guarantee that they are returned to you in the order of oldest to newest. 无法保证按照从最旧到最新的顺序将它们退回给您。 There are a variety of things that can affect the order in which rows are stored. 有许多因素会影响存储行的顺序。

请使用以下查询。

Select * from maxID order by myId desc limit 1,1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM