@AlirezaSoori: Несмотря на название, idэто просто столбец в таблице. Нет гарантии, что значения в idстолбце должны быть уникальными.
unutbu
1
@unutbu Предполагая, что idэто не первичный или уникальный ключ :) Учитывая имя, вполне вероятно, что это так. Также стоит отметить, что в зависимости от СУБД, которую вы используете, подход с подвыбором может быть гораздо менее эффективным.
Майкл Миор
3
@MichaelMior: idможет быть внешним ключом, и в этом случае он может быть не уникальным. Я провел несколько тестов, set profiling = 1; ...; show profilesи, похоже, наши решения имеют одинаковую производительность с MySQL. Насколько мне известно, знаете ли вы, какая СУБД имеет худшую производительность для подзапросов?
unutbu
1
Это может быть внешний ключ, но, как я уже сказал, я просто предполагаю, основываясь на имени, что это не так. Исторически известно, что MySQL плохо работает с подзапросами. Однако это значительно улучшилось в новых версиях, поэтому зависит от того, какую версию вы используете. Однако, если переосмыслить это, этот конкретный запрос может быть в порядке. Хотя выполнение запроса пару раз с профилированием не обязательно говорит об относительной производительности.
Майкл Миор
152
Вы также можете сделать
SELECTrowFROMtableORDERBYidDESCLIMIT1;
Это отсортирует строки по их идентификатору в порядке убывания и вернет первую строку. Это то же самое, что и возврат строки с максимальным ID. Это, конечно, предполагает, что idэто уникально среди всех строк. В противном случае может быть несколько строк с максимальным значением для, idи вы получите только одну.
Чтобы сделать именно то, что просит OP, я бы сделал это. Но другие ответы дают более
полное представление
@Dems Как так? Никаких объяснений по какому-либо другому ответу не дается? Я, конечно, тоже виноват в этом :(
Майкл Миор
Просто другие вопросы исправляют синтаксис без рефакторинга логики. Итак, OP учится правильно указывать этот конкретный sql.
MatBailie,
Справедливый вопрос :) Хотя другие ответы, возможно, все еще исправляют логику.
Майкл Миор,
А как насчет производительности? Я пришел сюда с таким запросом, который уже работает для меня, но мне было интересно, правильный ли это путь. Разве ORDER BY не является операцией O (n * log n)?
@ 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делает "полное сканирование" на столе.
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 ().
Ключевое слово TOP не работает в MySQL. Этот запрос работать не будет.
Анирудха Гупта
@toddmo: MySQL! И Sql-Server также не помогает другим людям. Вы имеете ввиду MS-SQL?
raiserle
@raiserle, вы можете помочь мне найти, где я что-то комментировал или публиковал по этому вопросу? Я нигде не вижу своего имени, прикрепленного к этому вопросу.
Ответы:
Вы можете использовать подзапрос:
SELECT row FROM table WHERE id=( SELECT max(id) FROM table )
Обратите внимание, что если значение
max(id)
не уникально, возвращается несколько строк.Если вам нужна только одна такая строка, используйте ответ @ MichaelMior,
SELECT row from table ORDER BY id DESC LIMIT 1
источник
id
это просто столбец в таблице. Нет гарантии, что значения вid
столбце должны быть уникальными.id
это не первичный или уникальный ключ :) Учитывая имя, вполне вероятно, что это так. Также стоит отметить, что в зависимости от СУБД, которую вы используете, подход с подвыбором может быть гораздо менее эффективным.id
может быть внешним ключом, и в этом случае он может быть не уникальным. Я провел несколько тестов,set profiling = 1; ...; show profiles
и, похоже, наши решения имеют одинаковую производительность с MySQL. Насколько мне известно, знаете ли вы, какая СУБД имеет худшую производительность для подзапросов?Вы также можете сделать
SELECT row FROM table ORDER BY id DESC LIMIT 1;
Это отсортирует строки по их идентификатору в порядке убывания и вернет первую строку. Это то же самое, что и возврат строки с максимальным ID. Это, конечно, предполагает, что
id
это уникально среди всех строк. В противном случае может быть несколько строк с максимальным значением для,id
и вы получите только одну.источник
SELECT * FROM table WHERE id = (SELECT MAX(id) FROM TABLE)
источник
SELECT entry FROM table WHERE id = MAX(id)
не получится ?!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
Вы не можете дать,
order by
потому чтоorder by
делает "полное сканирование" на столе.Следующий запрос лучше:
SELECT * FROM table WHERE id = (SELECT MAX(id) FROM table);
источник
ORDER BY
не будет выполнять полное сканирование, если вы предполагаете, чтоid
это первичный ключ таблицы. (А если это не так, это довольно неудачное название.) Если это не так, как вы ожидаетеMAX(id)
работать без полного сканирования таблицы? Если индекса нет, каждое значение все равно нужно проверять, чтобы найти максимум.Всегда можно использовать аналитические функции, которые дадут вам больше контроля.
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 ().
источник
Попробуйте с этим
SELECT top 1 id, Col2, row_number() over (order by id desc) FROM Table
источник