Как выбрать всю строку с наибольшим идентификатором в таблице?


Ответы:


238

Вы можете использовать подзапрос:

SELECT row 
FROM table 
WHERE id=(
    SELECT max(id) FROM table
    )

Обратите внимание, что если значение max(id)не уникально, возвращается несколько строк.

Если вам нужна только одна такая строка, используйте ответ @ MichaelMior,

SELECT row from table ORDER BY id DESC LIMIT 1

7
@AlirezaSoori: Несмотря на название, idэто просто столбец в таблице. Нет гарантии, что значения в idстолбце должны быть уникальными.
unutbu

1
@unutbu Предполагая, что idэто не первичный или уникальный ключ :) Учитывая имя, вполне вероятно, что это так. Также стоит отметить, что в зависимости от СУБД, которую вы используете, подход с подвыбором может быть гораздо менее эффективным.
Майкл Миор

3
@MichaelMior: idможет быть внешним ключом, и в этом случае он может быть не уникальным. Я провел несколько тестов, set profiling = 1; ...; show profilesи, похоже, наши решения имеют одинаковую производительность с MySQL. Насколько мне известно, знаете ли вы, какая СУБД имеет худшую производительность для подзапросов?
unutbu

1
Это может быть внешний ключ, но, как я уже сказал, я просто предполагаю, основываясь на имени, что это не так. Исторически известно, что MySQL плохо работает с подзапросами. Однако это значительно улучшилось в новых версиях, поэтому зависит от того, какую версию вы используете. Однако, если переосмыслить это, этот конкретный запрос может быть в порядке. Хотя выполнение запроса пару раз с профилированием не обязательно говорит об относительной производительности.
Майкл Миор

152

Вы также можете сделать

SELECT row FROM table ORDER BY id DESC LIMIT 1;

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


1
Чтобы сделать именно то, что просит OP, я бы сделал это. Но другие ответы дают более
полное представление

@Dems Как так? Никаких объяснений по какому-либо другому ответу не дается? Я, конечно, тоже виноват в этом :(
Майкл Миор

Просто другие вопросы исправляют синтаксис без рефакторинга логики. Итак, OP учится правильно указывать этот конкретный sql.
MatBailie,

Справедливый вопрос :) Хотя другие ответы, возможно, все еще исправляют логику.
Майкл Миор,

А как насчет производительности? Я пришел сюда с таким запросом, который уже работает для меня, но мне было интересно, правильный ли это путь. Разве ORDER BY не является операцией O (n * log n)?
dhill

27
SELECT * 
FROM table 
WHERE id = (SELECT MAX(id) FROM TABLE)

@ shA.t SELECT entry FROM table WHERE id = MAX(id)не получится ?!
oldboy

@ shA.t Кроме того, я пытаюсь сделать что-то вроде следующего: SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)мне просто нужна entry_timeсамая последняя запись в базе данных. Достаточно ли этого утверждения или оно должно быть?SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
oldboy

Самая последняя запись в результате запроса не имеет надежного значения, вам нужно иметь поле для времени вставки и так далее. Кстати, задайте свой вопрос отдельно, надеюсь, вы привлечете больше внимания -HTH;).
shA.t

17

Вы не можете дать, order byпотому что order byделает "полное сканирование" на столе.

Следующий запрос лучше:

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

18
ORDER BYне будет выполнять полное сканирование, если вы предполагаете, что idэто первичный ключ таблицы. (А если это не так, это довольно неудачное название.) Если это не так, как вы ожидаете MAX(id)работать без полного сканирования таблицы? Если индекса нет, каждое значение все равно нужно проверять, чтобы найти максимум.
Майкл Миор

@CakeLikeBoss ну, я действительно пробовал запрос "упорядочить по" и ваш "SELECT * FROM table WHERE id = (SELECT MAX (id) FROM table);" запрос по таблице из 114 строк, в то время как этот запрос каждый раз занимал ровно 0,0004 секунды, в то время как второй запрос занимал от 0,0007 до 0,0010 секунды, я повторил это несколько раз
prabhjot

1

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

select tmp.row from ( select row, rank() over(partition by id order by id desc ) as rnk from table) tmp where tmp.rnk=1

Если вы сталкиваетесь с проблемой с функцией rank () в зависимости от типа данных, можно также выбрать row_number () или density_rank ().


0

Попробуйте с этим

 SELECT top 1  id, Col2,  row_number() over (order by id desc)  FROM Table

10
Ключевое слово TOP не работает в MySQL. Этот запрос работать не будет.
Анирудха Гупта

@toddmo: MySQL! И Sql-Server также не помогает другим людям. Вы имеете ввиду MS-SQL?
raiserle

@raiserle, вы можете помочь мне найти, где я что-то комментировал или публиковал по этому вопросу? Я нигде не вижу своего имени, прикрепленного к этому вопросу.
toddmo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.