Получение последней записи из MySQL - PullRequest
2 голосов
/ 19 января 2012

Я использую mysql и столкнулся с некоторой проблемой. Я хочу получить последнюю вставленную строку.

<< Ниже приведены подробности >>

Ниже показано, как я создал таблицу.

create table maxID (myID varchar(4))

Я вставил четыре значения, как показано ниже

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

Когда я выполняю select myID, last_insert_id() as NewID from maxID, я получаю вывод, как показано ниже

myId NewID
A001   0  
A002   0  
A004   0  
A003   0    

Когда я попробовал приведенный ниже код,

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

Я получаю вывод, как показано ниже.

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

Однако, когда я использую код 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

Когда я использую where @rowid=4, я не получаю никаких данных в таблицах.

Ссылка для воспроизведения с данными

Примечание: Здесь я использую 4 только для получения желаемого результата. Позже я могу получить это из запроса (select max(rowid) from maxID)

Пожалуйста, предложите мне, что нужно сделать, если я хочу видеть только последнюю запись, т.е. A003.

Спасибо за ваше время.

Обновление:

У меня уже есть миллионы данных в моей таблице, поэтому я не могу добавить в нее новый столбец, как предлагается ниже.

Ответы [ 6 ]

5 голосов
/ 19 июня 2012

Почти готово.Вам удалось получить порядок вставки.Итак:

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

В своей консоли я получаю следующее:

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)

Демо

ОБНОВЛЕНИЕ

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

  • При каких условиях сортировка SELECT по умолчанию соответствует порядку вставки?
  • Можно ли получить последнюю вставленную запись в таблице без инкрементного идентификатора или метки времени вставки?

Я знаю, что это не ответ, но постановка проблемы ограничивает проблему.

2 голосов
/ 21 июня 2012

Кажется, что SELECT не гарантирует возвращение строк в каком-либо определенном порядке (конечно, без использования условия ORDER BY).

Согласно стандарту SQL-92 (стр. 373):

Если <упорядочение по предложению> не указано, то таблица, указанная в <спецификации курсора>, равна T, а порядок строк в T соответствует реализации.

Хорошо, MySQL не полностью совместим с SQL-92, но это серьезный намек.

Laurynas Biveinis (очевидно, связан с Percona ) также заявляет :

Порядок строк в отсутствие предложения ORDER BY (...) может отличаться из-за фазы луны, и это нормально.

В руководстве MySQL говорится об InnoDB:

InnoDB всегда упорядочивает строки таблицы в соответствии с индексом [a PRIMARY KEY или NOT NULL UNIQUE] , если таковой имеется.

Насколько мне известно, я предполагаю MySQL также может переупорядочивать строки после OPTIMIZE TABLE или даже повторно использовать пустые пробелы после многих удалений и вставок (я попытался найти пример этого, но пока не получилось).

Учитывая структуру вашей таблицы, нижняя линия равнак сожалению, так много факторов могли изменить порядок строк;Я не вижу решения, чтобы надежно определить порядок их вставки.Конечно, если вы не сохранили все двоичные журналы с момента создания таблицы;)

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

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

2 голосов
/ 19 января 2012

Из вашего скрипта вставки A004 не последняя вставленная запись. Это третий. Если вы хотите получить последнюю запись в алфавитном порядке (которой является A004), вы должны использовать

select myID from maxID order by myID desc limit 1

Если вам нужна последняя вставленная строка, почему бы вам просто не добавить колонку автоинкремента в вашу таблицу? В этом смысл таких столбцов. Столбец автоинкремента не обязательно должен быть ПК (так должно быть, но не обязательно, если у вас нет выбора).

1 голос
/ 19 января 2012

Как упоминалось в справке MySQL для last_insert_id, вы можете использовать ее только с ** столбцами с автоинкрементом. Это означает, что вы не можете заставить MySQL найти для вас последнюю вставленную строку, если вы не знаете что-то о порядке идентификаторов. Если они отсортированы, как показывает ваш пример, вы можете использовать

SELECT *
FROM maxID
WHERE myId = max(myId)

Но я предлагаю добавить столбец автоинкремента в таблицу, а затем использовать = last_insert_id() в предложении WHERE. См. Также на этой странице для получения информации о том, как получить последний идентификатор.

0 голосов
/ 19 января 2012

Пожалуйста, используйте следующий запрос.

Select * from maxID order by myId desc limit 1,1;
0 голосов
/ 19 января 2012

last_insert_id не работает, потому что возвращает только последнее значение, сгенерированное полем автоинкремента. Однако я думаю, что решение может быть на правильном пути. Я бы предложил добавить еще один столбец с автоматическим приращением. Затем вы можете вставить данные и получить строку, которую вы только что вставили, выберите last_insert_id (). Чтобы получить самую последнюю строку (вставленную любым процессом), выберите максимальное число для нового столбца или отсортируйте по нему desc.

Если вы хотите использовать столбец varchar, вы можете выполнить алфавитную сортировку, но это не гарантирует, что это будет последняя добавленная вами строка или даже самая последняя добавленная строка.

Еще одно решение, которое я могу придумать: может делать то, что вам нужно, - создать хранимую процедуру, которая создает строку, вставляет ее в таблицу и затем возвращает ее вам.

Ваше использование @rowid просто означает, что строки заказа возвращаются вам. Там нет никакой гарантии, что они будут возвращены вам в порядке от старшего к новейшему. Существует множество вещей, которые могут повлиять на порядок хранения строк.

...