Oracle найти максимальное значение

Обновлено: 01.07.2024

Мне нужно выбрать каждый отдельный home , удерживающий максимальное значение datetime .

Результат:

Не работает. Набор результатов имеет 130 строк, хотя в базе данных содержится 187. Результат включает в себя некоторые дубликаты home .

Неа. Дает все записи.

С различными результатами.

Ты так близко! Все, что вам нужно сделать, это выбрать BOTH home и it max date time, а затем присоединиться к таблице topten в полях BOTH:

Проверьте это на предмет отличия, если два одинаковых максимальных времени и даты будут в одном доме (с разными игроками) Я думаю, что классический способ сделать это с помощью естественного соединения: «SELECT tt. * FROM topten tt NATURAL JOIN (SELECT home, MAX (datetime) AS datetime FROM topten GROUP BY home) mostrecent;» Точно такой же запрос, но, возможно, более читаемый @ max-gontar, как бы ты проверил на отличимость, если бы не player: home = 1: N? @Randall, не уверен, правильно ли я понял ваш вопрос с комментариями, пожалуйста, задайте новый вопрос SO (больше возможностей для описания и больше шансов на него ответить), спасибо! Если это очень большой стол, потребовалось бы много времени, если бы в доме не было индекса. почему не SELECT home, MAX(datetime) AS MaxDateTime,player,resource FROM topten GROUP BY home , я что-то пропустил? Что делать, если есть две строки с одинаковыми значениями полей home и datetime? Может кто-нибудь сказать, почему бы не select * from topten GROUP BY home ORDER BY datetime DESC ? @ Молодая проблема в вашем запросе состоит в том, что он может вернуть id , player и resource не максимальной строки для данного дома, т.е. для home = 10, вы можете получить: 3 | 10 | 04/03/2009 | john | 300 Другими словами, это не гарантирует, что весь столбец строки в наборе результатов будет принадлежать max (datetime) для данного дома. @ me1111 проблема с вашим запросом в том, что он может / не может возвращать строку ith max (datetime) для данного дома. Причина в том, что GROUP BY извлекает любую случайную строку для каждого дома, а ORDER BY просто сортирует общий результат, полученный GROUP BY. @Parker Использование NATURAL JOIN подобного этому, может работать в этом (простом) случае, но не всегда надежно, так как не всегда удаляет все строки, которые должны быть для более сложных таблиц. Для рабочих представлений безопаснее явно указать условие соединения. Многие люди указали на проблемы, не предлагая контрпримеров, которые бы показывали лучшее решение . просто заставляет читателя колебаться в реализации ответа. Что касается комментария @KemalDuran, приведенного выше, если есть две строки с одинаковыми полями home и datetime, вам нужно взять решение Michael La Voie и добавить MAX(id) AS MaxID во внутренний SELECT а затем перейти и добавьте еще одну строку AND tt.id = groupedtt.MaxID в конце. @cardamom, почему это должно выбрать только различные значения? @sactiw, я не мог понять, что ты сказал в ответ на комментарий Янга. Позвольте мне процитировать ваш комментарий: «проблема с вашим запросом в том, что он может возвращать id, игрока и ресурс не-max строки для данного дома» - почему это должно происходить при применении GROUP BY и выборе MAX(datetime) вверх? @IstiaqueAhmed его запрос будет возвращать «Максимум определенного столбца на группу», но здесь нам действительно нужно «Строки, содержащие групповой максимум определенного столбца». Для получения дополнительной информации см. Примеры в разделе: MySQL запросы @IstiaqueAhmed Мне потребовалось немного времени, чтобы вспомнить, что я делал, когда я использовал это решение и написал этот комментарий. @KemalDuran спросил, а как насчет того, есть ли в двух строках одинаковые значения полей home и datetime? Мой комментарий выше добавляет третью группировку для решения этой проблемы вокруг поля id которое определенно уникально в отличие, скажем, от datetime или player. Решение @MichaelLaVoie имеет 2 группировки, и некоторые из нас нуждались в этом решении для ситуаций, когда этого было недостаточно.

Ниже приведена версия T-SQL:

ИЗМЕНИТЬ
К сожалению, в MySQL нет функции RANK() OVER.
Но его можно эмулировать, см. Функции эмуляции аналитического (AKA) с MySQL.
Итак, это версия MySQL:

ах, так что вы используете MySQL. Вот с чего вам следует начать! Я скоро обновлю ответ. BUG: замените "RANK ()" на "ROW_NUMBER ()". Если у вас есть связь (вызванная дублированием значения даты), у вас будет две записи с «1» для N.

Самое быстрое решение MySQL без внутренних запросов и без GROUP BY :

Объяснение

Соедините таблицу с самим собой, используя столбец home . Использование LEFT JOIN гарантирует, что все строки из таблицы m появятся в результирующем наборе. Те, которые не имеют соответствия в таблице b , будут иметь NULL для столбцов b .

Другое условие в JOIN требует совместить только строки из b , которые имеют большее значение в столбце datetime , чем строка из m .

Используя данные, опубликованные в вопросе, LEFT JOIN создаст эти пары:

Наконец, предложение WHERE хранит только пары с NULL в столбцах b (они помечены знаком * в таблице выше); это означает, что из-за второго условия из предложения JOIN строка, выбранная из m , имеет наибольшее значение в столбце datetime .

С SQLite , первый намного медленнее, чем версия La Voie, когда в сопоставленном столбце нет индекса (т. Е. «Home»). (Протестировано с 24 тыс. Строк, что дает 13 тыс. Строк) Это лучший ответ, если вы покажете план выполнения, вы увидите на один шаг меньше с этим запросом что произойдет , если 2 строки имеет один и тот же home и datetime и datetime и home datetime является максимальной для этого конкретного home ? Обе строки появляются в наборе результатов. Этот ответ является доказательством концепции. В вашем реальном коде у вас, вероятно, есть другой критерий, чтобы выбрать только один из них в этой ситуации (возможно, первый или последний или вы используете другой столбец для принятия решения). Просто добавьте этот критерий в качестве нового условия в предложении ON . Fe . ON . AND m.id < b.id чтобы сохранить самую последнюю запись (ту, которая имеет наибольший id ), когда две строки имеют одинаковые значения в столбцах home и datetime и это максимальное значение datetime .

Это будет работать, даже если у вас есть две или несколько строк для каждого home с равными DATETIME :

Нам действительно нужен этот DIV для проверки ошибок компиляции :) WHERE ti.home = t1.home - можете ли вы объяснить синтаксис? @IstiaqueAhmed: что именно вы здесь не понимаете? Это коррелированный запрос, а упомянутое вами выражение является условием корреляции. @Quassnoi, The select запрос , который имеет линию WHERE ti.home = t1.home не нуждается в FROM пункта , который определяет t1 . Так как это используется?

Я думаю, что это даст вам желаемый результат:

НО, если вам нужны и другие столбцы, просто сделайте соединение с исходной таблицей (проверьте Michael La Voie ответ)

Так как люди, похоже, продолжают работать в этом потоке (диапазон комментариев составляет от 1,5 года), это не намного проще:

SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home

Никаких функций агрегации не требуется.

Это определенно не будет работать в SQL Server или Oracle, хотя, похоже, может работать в MySQL. Это действительно красиво! Как это работает? Используя DESC и столбец возврата группы по умолчанию? Так что, если бы я изменил его на datetime ASC, он вернул бы самую раннюю строку для каждого дома? Это упрощение не работает, если у вас есть неагрегированные столбцы (в MySQL).

Вы также можете попробовать это, а для больших таблиц производительность запросов будет лучше. Он работает, когда для каждого дома не более двух записей, а их даты разные. Лучший общий запрос MySQL - один из Майкла Ла Фой выше.

Или в случае Postgres или тех dbs, которые предоставляют аналитические функции, попробуйте

Этот ответ правильный? Я пытался его использовать, но он пытается не выбрать запись с самой новой датой для «home», а только удаляет запись с самой старой датой. Вот пример: SQLfiddle @kidOfDeath - обновил мой ответ контекстом и запросом Postgres С SQLite , первый намного медленнее, чем версия La Voie, когда в сопоставленном столбце нет индекса (т. Е. «Home»).

Это работает на Oracle:

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

Попробуйте это для SQL Server:

Почему бы не использовать: SELECT home, MAX (datetime) AS MaxDateTime, проигрыватель, ресурс FROM topten GROUP BY home Я что-то пропустил?

Это было бы допустимо только для MySQL и только для версий до 5.7 (?) Или после 5.7 с отключенным ONLY_FULL_GROUP_BY, поскольку это ВЫБОР столбцов, которые не были агрегированы / GROUPed (player, resource), что означает, что MySQL предоставит случайно выбранные значения для этих два поля результата. Это не будет проблемой для столбца игрока, так как он соотносится с домашним столбцом, но столбец ресурсов не будет соотноситься со столбцом home или datetime, и вы не сможете гарантировать, какое значение ресурса вы получите. +1 для объяснения, НО по заданному вопросу этот запрос не вернет expected результат в MySQL версии 5.6 и before и я сильно сомневаюсь, что он будет вести себя иначе в MySQL версии 5.7 и after . @simpleuser, `Это не будет проблемой для столбца игрока, так как он соотносится с домашним столбцом` - можете ли вы объяснить больше? @IstiaqueAhmed, как я смотрю на это снова, это утверждение неверно. Я думал, что у каждого игрока всегда было одно и то же домашнее значение, но теперь я вижу, что это не так, поэтому такая же проблема случайного выбора будет возникать и для этого столбца.

Вот версия MySQL, которая печатает только одну запись, в которой есть дубликаты MAX (datetime) в группе.

Примеры данных

Версия MySQL с пользовательской переменной

Примером этого утверждения является то, что на MariaDB 10.1 это работало, когда я использовал 5 столбцов из таблицы t1. Как только я добавил шестой столбец, явно испорченный «естественной» сортировкой данных в исходной таблице, он перестал работать. Причина в том, что данные в подвыборке стали неупорядоченными, и поэтому у меня было условие "is_first_appear = 1", встреченное несколько раз. Тот же код, с теми же данными, работал на Percona хорошо. Проверьте это на предмет отличия, если два одинаковых максимальных времени и даты будут в одном доме (с разными игроками) псевдонимом для max(datetime) является datetime . Не создаст ли это проблемы?

Другой путь к последней строке для каждой группы с использованием подзапроса, который в основном вычисляет ранг для каждой строки для каждой группы, а затем отфильтровывает ваши последние строки так же, как rank = 1

Вот визуальная демонстрация для ранга no для каждой строки для лучшего понимания

Прочитав несколько комментариев , если есть две строки, которые имеют одинаковые значения поля "home" и "datetime"?

Выше запроса не удастся и вернет более 1 строки для указанной выше ситуации. Чтобы скрыть эту ситуацию, потребуется другой критерий/параметр/столбец, чтобы решить, какую строку следует принять, которая попадает в ситуацию выше. Просматривая образец данных, я предполагаю, что есть столбец первичного ключа id , который должен быть установлен на автоматическое увеличение. Поэтому мы можем использовать этот столбец, чтобы выбрать самую последнюю строку, изменив тот же запрос с помощью оператора CASE , например

Выше запроса будет выбирать строку с наивысшим идентификатором среди тех же datetime значений

Будем учиться подводить итоги. Нет, это ещё не итоги изучения SQL, а итоги значений столбцов таблиц базы данных. Агрегатные функции SQL действуют в отношении значений столбца с целью получения единого результирующего значения. Наиболее часто применяются агрегатные функции SQL SUM, MIN, MAX, AVG и COUNT. Следует различать два случая применения агрегатных функций. Первый: агрегатные функции используются сами по себе и возвращают одно результирующее значение. Второй: агрегатные функции используются с оператором SQL GROUP BY, то есть с группировкой по полям (столбцам) для получения результирующих значений в каждой группе. Рассмотрим сначала случаи использования агрегатных функций без группировки.

Функция SQL SUM

Функция SQL SUM возвращает сумму значений столбца таблицы базы данных. Она может применяться только к столбцам, значениями которых являются числа. Запросы SQL для получения результирующей суммы начинаются так:

После этого выражения следует FROM (ИМЯ_ТАБЛИЦЫ), а далее с помощью конструкции WHERE может быть задано условие. Кроме того, перед именем столбца может быть указано DISTINCT, и это означает, что учитываться будут только уникальные значения. По умолчанию же учитываются все значения (для этого можно особо указать не DISTINCT, а ALL, но слово ALL не является обязательным).

Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке .

Сначала работать будем с базой данных фирмы - Company1. Скрипт для создания этой базы данных, её таблиц и заполения таблиц данными - в файле по этой ссылке .

Пример 1. Есть база данных фирмы с данными о её подразделениях и сотрудниках. Таблица Staff помимо всего имеет столбец с данными о заработной плате сотрудников. Выборка из таблицы имеет следующий вид (для увеличения картинки щёлкнуть по ней левой кнопкой мыши):


Для получения суммы размеров всех заработных плат используем следующий запрос (на MS SQL Server - с предваряющей конструкцией USE company1;):

Этот запрос вернёт значение 287664,63.

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

Пример 2. Вывести сумму комиссионных, получаемых всеми сотрудниками с должностью Clerk.

Функция SQL MIN

Функция SQL MIN также действует в отношении столбцов, значениями которых являются числа и возвращает минимальное среди всех значений столбца. Эта функция имеет синтаксис аналогичный синтаксису функции SUM.

Пример 3. База данных и таблица - те же, что и в примере 1.

Требуется узнать минимальную заработную плату сотрудников отдела с номером 42. Для этого пишем следующий запрос (на MS SQL Server - с предваряющей конструкцией USE company1;):

Запрос вернёт значение 10505,90.

И вновь упражнение для самостоятельного решения. В этом и некоторых других упражнениях потребуется уже не только таблица Staff, но и таблица Org, содержащая данные о подразделениях фирмы:


Пример 4. К таблице Staff добавляется таблица Org, содержащая данные о подразделениях фирмы. Вывести минимальное количество лет, проработанных одним сотрудником в отделе, расположенном в Бостоне.

Функция SQL MAX

Аналогично работает и имеет аналогичный синтаксис функция SQL MAX, которая применяется, когда требуется определить максимальное значение среди всех значений столбца.

Пример 5. База данных и таблица - те же, что и в предыдущих примерах.

Требуется узнать максимальную заработную плату сотрудников отдела с номером 42. Для этого пишем следующий запрос (на MS SQL Server - с предваряющей конструкцией USE company1;):

Запрос вернёт значение 18352,80

Пришло время упражнения для самостоятельного решения.

Пример 6. Вновь работаем с двумя таблицами - Staff и Org. Вывести название отдела и максимальное значение комиссионных, получаемых одним сотрудником в отделе, относящемуся к группе отделов (Division) Eastern. Использовать JOIN (соединение таблиц).

Функция SQL AVG

Указанное в отношении синтаксиса для предыдущих описанных функций верно и в отношении функции SQL AVG. Эта функция возвращает среднее значение среди всех значений столбца.

Пример 7. База данных и таблица - те же, что и в предыдущих примерах.

Пусть требуется узнать средний трудовой стаж сотрудников отдела с номером 42. Для этого пишем следующий запрос (на MS SQL Server - с предваряющей конструкцией USE company1;):

Результатом будет значение 6,33

В следующем упражнении для самостоятельного решения помимо агрегатной функции требуется использовать также предикат BETWEEN.

Пример 8. Работаем с одной таблицей - Staff. Вывести среднюю зарплату сотрудников со стажем от 4 до 6 лет.

Функция SQL COUNT

Функция SQL COUNT возвращает количество записей таблицы базы данных. Если в запросе указать SELECT COUNT(ИМЯ_СТОЛБЦА) . то результатом будет количество записей без учёта тех записей, в которых значением столбца является NULL (неопределённое). Если использовать в качестве аргумента звёздочку и начать запрос SELECT COUNT(*) . то результатом будет количество всех записей (строк) таблицы.

Пример 9. База данных и таблица - те же, что и в предыдущих примерах.

Требуется узнать число всех сотрудников, которые получают комиссионные. Число сотрудников, у которых значения столбца Comm - не NULL, вернёт следующий запрос (на MS SQL Server - с предваряющей конструкцией USE company1;):

Результатом будет значение 11.

Пример 10. База данных и таблица - те же, что и в предыдущих примерах.

Если требуется узнать общее количество записей в таблице, то применяем запрос со звёздочкой в качестве аргумента функции COUNT (на MS SQL Server - с предваряющей конструкцией USE company1;):

Результатом будет значение 17.

В следующем упражнении для самостоятельного решения потребуется использовать подзапрос.

Пример 11. Работаем с одной таблицей - Staff. Вывести число сотрудников в отделе планирования (Plains).

Агрегатные функции вместе с SQL GROUP BY (группировкой)

Теперь рассмотрим применение агрегатных функций вместе с оператором SQL GROUP BY. Оператор SQL GROUP BY служит для группировки результирующих значений по столбцам таблицы базы данных. На сайте есть урок, посвящённый отдельно этому оператору.

Работать будем с базой данных "Портал объявлений 1". Скрипт для создания этой базы данных, её таблицы и заполения таблицы данных - в файле по этой ссылке .

Пример 12. Итак, есть база данных портала объявлений. В ней есть таблица Ads, содержащая данные об объявлениях, поданных за неделю. Столбец Category содержит данные о больших категориях объявлений (например, Недвижимость), а столбец Parts - о более мелких частях, входящих в категории (например, части Квартиры и Дачи являются частями категории Недвижимость). Столбец Units содержит данные о количестве поданных объявлений, а столбец Money - о денежных суммах, вырученных за подачу объявлений.

CategoryPartUnitsMoney
ТранспортАвтомашины11017600
НедвижимостьКвартиры8918690
НедвижимостьДачи5711970
ТранспортМотоциклы13120960
СтройматериалыДоски687140
ЭлектротехникаТелевизоры1278255
ЭлектротехникаХолодильники1378905
СтройматериалыРегипс11211760
ДосугКниги966240
НедвижимостьДома479870
ДосугМузыка1177605
ДосугИгры412665

Используя оператор SQL GROUP BY, найти суммы денег, вырученных за подачу объявлений в каждой категории. Пишем следующий запрос (на MS SQL Server - с предваряющей конструкцией USE adportal1;):

SELECT Category, SUM (Money) AS Money FROM ADS GROUP BY Category

Результатом будет следующая таблица:

CategoryMoney
Досуг16510
Недвижимость40530
Стройматериалы18900
Транспорт38560
Электротехника17160

Пример 13. База данных и таблица - та же, что в предыдущем примере.

Используя оператор SQL GROUP BY, выяснить, в какой части каждой категории было подано наибольшее число объявлений. Пишем следующий запрос (на MS SQL Server - с предваряющей конструкцией USE adportal1;):

SELECT Category, Part, MAX (Units) AS Maximum FROM ADS GROUP BY Category

Результатом будет следующая таблица:

CategoryPartMaximum
ДосугМузыка117
НедвижимостьКвартиры89
СтройматериалыРегипс112
ТранспортМотоциклы131
ЭлектротехникаХолодильники137

Итоговые и индивидуальные значения в одной таблице можно получить объединением результатов запросов с помощью оператора UNION.

В этой части вы увидите использование функции SQL MAX () для типа даты столбца таблицы.

Пример:

Пример таблицы: заказы

Чтобы получить максимальное значение ord_date из таблицы orders, можно использовать следующий оператор SQL:

SQL MAX () для значения даты с помощью где

Чтобы получить данные «ord_num», «ord_amount», «ord_date», «agent_code» из таблицы «orders» при следующих условиях:

1. «ord_date» равно максимальному «ord_date»,

можно использовать следующий оператор SQL:

SQL MAX () на дату с группировкой по

Чтобы получить данные «agent_code» и максимального значения «ord_date» с заданным пользователем псевдонимом столбца «Max Date» для каждого агента из таблицы заказов со следующим условием:

можно использовать следующий оператор SQL:

SQL MAX () на значение даты с подзапросом

Чтобы получить данные «agent_code», «ord_date» и «cust_code» из таблицы «orders» при следующих условиях:

можно использовать следующий оператор SQL:

SQL MAX () для значения даты с использованием соединения

Пример таблицы: заказы

Пример таблицы: отправка

1. «ord_date» должно быть наибольшим (максимальным) из таблицы «orders»,

2. наибольшее (максимальное) значение ord_date должно быть равно таблице ord_date of orders,

можно использовать следующий оператор SQL:

Примечание. Выводы указанного оператора SQL, показанного здесь, взяты с использованием Oracle Database 10g Express Edition.

Вот слайд-презентация всех агрегатных функций.

Упражнения по SQL

  • Упражнения по SQL, практика, решение
  • SQL Получить данные из таблиц [33 Упражнения]
  • Булевы и реляционные операторы SQL [12 упражнений]
  • Подстановочные знаки SQL и специальные операторы [22 упражнения]
  • Агрегатные функции SQL [25 упражнений]
  • Вывод запроса форматирования SQL [10 упражнений]
  • SQL-запросы к нескольким таблицам [7 упражнений]
  • ФИЛЬТРАЦИЯ И СОРТИРОВКА в базе данных персонала [38 упражнений]
  • SQL СОЕДИНЯЕТ
    • SQL СОЕДИНЯЕТСЯ [29 упражнений]
    • SQL присоединяется к базе данных HR [27 упражнений]
    • ПОДПИСИ SQL [39 упражнений]
    • SQL ПОДПИСИ по базе данных HR [55 упражнений]
    • ОСНОВНЫЕ запросы к базе данных фильмов [10 упражнений]
    • ПОДПИСКИ на фильм База данных [16 упражнений]
    • ПРИСОЕДИНЯЕТСЯ к базе данных фильма [24 упражнения]
    • Вступление
    • ОСНОВНЫЕ запросы по футболу базы данных [29 упражнений]
    • ПОДПИСКИ по футбольной базе данных [33 упражнения]
    • ПРИСОЕДИНЯЕТСЯ к запросам по футбольной базе данных [61 упражнений]
    • Вступление
    • ОСНОВНЫЕ, ПОДПИСИ И СОЕДИНЕНИЯ [39 упражнений]
    • ОСНОВНЫЕ запросы к базе данных сотрудников [115 упражнений]
    • БРОНИРОВАНИЕ на сотрудника База данных [77 Упражнения]

    Хотите улучшить вышеуказанную статью? Вносите свои заметки / комментарии / примеры через Disqus.

    у меня есть эта таблица для документов (упрощенная версия здесь):

    Как выбрать одну строку на id и только самый большой rev?
    С приведенными выше данными результат должен содержать две строки: [1, 3, . ] и [2, 1, ..] . Я использую MySQL.

    В настоящее время я использую проверки в while цикл для обнаружения и перезаписи старых оборотов из resultset. Но разве это единственный способ достичь результата? Нет среда SQL решение?

    обновление
    Как показывают ответы, там is решение SQL и вот демонстрация sqlfiddle.

    на первый взгляд.

    все, что вам нужно-это GROUP BY п. с MAX агрегатная функция:

    это никогда не бывает так просто, не так ли?

    я только что заметил, что вам нужно

    Я предпочитаю использовать как можно меньше кода.

    Вы можете сделать это с помощью IN попробуйте это:

    на мой взгляд, это менее сложно. легче читать и поддерживать.

    еще одно решение-использовать коррелированный подзапрос:

    наличие индекса на (id, rev)отображает подзапрос почти как простой поиск.

    Ниже приведены сравнения с решениями в ответе @AdrianCarneiro (subquery, leftjoin), основанными на измерениях MySQL с таблицей InnoDB

    1million записей, размер группы: 1-3.

    в то время как для полного сканирования таблицы подзапрос/левое соединение/коррелированные тайминги относятся друг к другу как 6/8/9, когда дело доходит до прямой поиск или пакет ( id in (1,2,3) ), подзапрос намного медленнее остальных (из-за перезапуска подзапроса). Однако я не мог различать левое соединение и коррелированные решения в скорости.

    одна заключительная нота, поскольку leftjoin создает N * (n+1)/2 присоединяется к группам, его производительность может сильно зависеть от размера групп.

    Я не могу ручаться за производительность, но вот трюк, вдохновленный ограничениями Microsoft Excel. Он имеет некоторые хорошие особенности

    ХОРОШЕЕ

    • он должен принудительно вернуть только одну "максимальную запись", даже если есть галстук (иногда полезный)
    • это не требует соединения

    подход

    это немного уродливо и требует, чтобы вы знали что-то о диапазоне допустимых значения rev

    Я поражен тем, что ни один ответ не предложил решение функции окна SQL:

    добавлено в SQL standard ANSI / ISO Standard SQL: 2003 и позже расширено с ANSI / ISO Standard SQL: 2008, оконные (или оконные) функции доступны со всеми основными поставщиками в настоящее время. Существует больше типов ранговых функций, доступных для решения проблемы галстука: RANK, DENSE_RANK, PERSENT_RANK .

    Я думаю, что это самое простое решение :

    • SELECT *: возврат всех полей.
    • от сотрудника: таблица искала дальше.
    • (выберите *. ) подзапрос: вернуть всех людей, отсортированных по зарплате.
    • группа по employeesub.Зарплата:: заставьте строку зарплаты каждого сотрудника, отсортированную сверху, быть возвращенным результатом.

    Если вам понадобится только одна строка, это еще проще:

    Я также думаю, что это проще всего разбить, понять и модифицировать для других целей:

    • заказ сотрудником.Зарплата DESC: заказать результаты по зарплате, с самой высокой заработной платой в первую очередь.
    • LIMIT 1: верните только один результат.

    понимая этот подход, решение любой из этих подобных проблем становится тривиальным: получить сотрудника с самой низкой зарплатой (изменить DESC на ASC), получить первую десятку зарабатывающих сотрудников (изменить предел 1 на предел 10), сортировать с помощью другого поля (порядок изменения по сотруднику.Зарплата на заказ по работнику.Комиссия) и др..

    что-то вроде этого?

    Так как это самый популярный вопрос в отношении этой проблемы, я повторно опубликую еще один ответ на него здесь:

    похоже, что есть простой способ сделать это (но только в MySQL):

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

    EDIT: хотя это решение работает для многих людей, оно может быть нестабильным в долгосрочной перспективе, поскольку MySQL не гарантирует, что оператор GROUP BY вернет значимые значения для столбцов не в списке GROUP BY. Поэтому используйте это решение на свой страх и риск

    мне нравится использовать NOT EXIST - основанное решение для этой проблемы:

    третье решение, которое я едва ли когда-либо видел, является специфичным для MySQL и выглядит так:

    Да, это выглядит ужасно (преобразование в строку и обратно и т. д.) но по моему опыту это обычно быстрее, чем другие решения. Возможно, это только для моих случаев использования, но я использовал его на таблицах с миллионами записей и многими уникальными идентификаторами. Возможно, это потому, что MySQL довольно плохо оптимизирует другие решения (по крайней мере, в дни 5.0, когда я придумал это решение.)

    важно то, что GROUP_CONCAT имеет максимальную длину для строки, которую он может создать. Вероятно, вы хотите поднять этот предел, установив group_concat_max_len переменной. И имейте в виду, что это будет ограничение на масштабирование, если у вас большое количество строк.

    В любом случае, вышеизложенное не работает напрямую, если ваше поле содержимого уже является текстом. В этом случае вы, вероятно, захотите использовать другой разделитель, например \0. Вы также столкнетесь с group_concat_max_len ограничение быстрее.

    Если у вас много полей в инструкции select и вы хотите получить последнее значение для всех этих полей с помощью оптимизированного кода:

    Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.

    Аргументы

    ALL
    Применяет агрегатную функцию ко всем значениям. ALL является параметром по умолчанию.

    DISTINCT
    Указывает, что учитывается каждое уникальное значение. Параметр DISTINCT не имеет смысла при использовании функцией MAX и доступен только для совместимости со стандартом ISO.

    expression
    Может быть константой, именем столбца или функцией, а также любым сочетанием арифметических, побитовых и строковых операторов. MAX можно использовать со столбцами numeric, character, uniqueidentifier и datetime, но не со столбцами bit. Агрегатные функции и вложенные запросы не допускаются.

    Дополнительные сведения см. в разделе Выражения (Transact-SQL).

    OVER ( partition_by_clause [ order_by_clause ] )
    partition_by_clause делит результирующий набор, полученный с помощью предложения FROM, на секции, к которым применяется функция. Если этот параметр не указан, функция обрабатывает все строки результирующего набора запроса как отдельные группы. order_by_clause определяет логический порядок, в котором выполняется операция. partition_by_clause использовать обязательно. Дополнительные сведения см. в статье Предложение OVER (Transact-SQL).

    Типы возвращаемых данных

    Возвращает то же значение, что и expression.

    Комментарии

    При выполнении функции MAX все значения NULL пропускаются.

    MAX возвращает NULL, если нет строк для выбора.

    При использовании со столбцами, содержащими символьные значения, функция MAX находит наибольшее значение в упорядоченной последовательности.

    MAX — это детерминированная функция, если она используется без предложений OVER и ORDER BY. Она не детерминирована при использовании с предложениями OVER и ORDER BY. Дополнительные сведения см. в разделе Deterministic and Nondeterministic Functions.

    Примеры

    A. Простой пример

    В следующем примере возвращается наибольший (максимальный) размер налога в базе данных AdventureWorks2012.

    Б. Использование предложения OVER

    В приведенном ниже примере рассматривается применение функций MIN, MAX, AVG и COUNT с предложением OVER для получения статистических значений для каждого из отделов в таблице HumanResources.Department в базе данных AdventureWorks2012.

    В. Использование MAX с символьными данными

    В приведенном ниже примере возвращается имя базы данных, которое является последним при сортировке по алфавиту. В нем используется WHERE database_id < 5 для обработки только системных баз данных.

    Читайте также: