Як вибрати цілий рядок із найбільшим ідентифікатором у таблиці?


Відповіді:


228

Ви можете використовувати підвідбір:

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

Зауважте, що якщо значення max(id)не унікальне, повертається кілька рядків.

Якщо ви хочете лише один такий рядок, використовуйте відповідь @ MichaelMior,

SELECT row from table ORDER BY id DESC LIMIT 1

6
@AlirezaSoori: Незважаючи на назву, idце лише стовпець у таблиці. Немає гарантії, що значення в idстовпці повинні бути унікальними.
unutbu

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

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

1
Це може бути іноземним ключем, але, як я вже сказав, я лише здогадуюсь, виходячи з назви, що це не так. Історично відомо, що MySQL має низькі показники роботи з підборами. Це значно покращилося в нових версіях, тому залежить, яку версію ви використовуєте. Однак, переосмисливши це, цей конкретний запит може бути в порядку. Хоча виконання запиту кілька разів із профілюванням, не обов'язково говорить багато про відносну ефективність.
Майкл Міор

149

Ви також можете зробити

SELECT row FROM table ORDER BY id DESC LIMIT 1;

Це буде сортувати рядки за їх ідентифікаційним кодом у порядку зменшення та повертати перший рядок. Це те саме, що повертати рядок з максимальним ідентифікатором. Звичайно, це передбачає, що idце унікально серед усіх рядів. Інакше може бути кілька рядків із максимальним значенням, idі ви отримаєте лише один.


Щоб спеціально робити те, що просить ОП, я би зробив це. Але інші відповіді дають кращу освіту структурі SQL :)
MatBailie

@Dems Як так? Ніяких пояснень не надано жодної іншої відповіді? Я, звичайно, і в цьому винен :(
Майкл Міор

Просто інші питання виправляють синтаксис, не змінюючи логіки. Отже, ОП дізнається, як правильно вказати конкретний sql.
MatBailie

Справедливий пункт :) Хоча інші відповіді, певно, все ще виправляють логіку.
Майкл Міор

А як щодо продуктивності? Я потрапив сюди з таким запитом, який вже працює для мене, але мені було цікаво, чи це правильний шлях. Чи НЕ ЗАМОВЛЕНО операцією O (n * log n)?
холод

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 () залежно від типу даних, ви також можете вибрати один з рядків_bumber () або щільний_rank ().


0

Спробуйте з цим

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

9
Ключове слово TOP не працює в MySQL. Цей запит не працюватиме.
Анірудха Гупта

@toddmo: MySQL! І Sql-сервер також не корисний для інших людей. Ви маєте на увазі MS-SQL?
рейзерле

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