MySQL: выберите максимум (оценка) не возвращает соответствующие данные строки - PullRequest
2 голосов
/ 17 января 2010

если у меня есть, например, таблица результатов:

    user game score timestamp
    1    50   50    date
    2    60   40    date
    3    70   25    date
    4    80   18    date

и я выполню запрос:

select user, game, max(score), timestamp from scores

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

Ответы [ 3 ]

19 голосов
/ 17 января 2010

Вы используете MAX, который является агрегатной функцией. Агрегатные функции позволяют обрабатывать несколько строк в таблице как группу. Если вы не сделаете ничего особенного, все строки во всей таблице будут использоваться как одна большая группа, а когда есть такая агрегированная функция, как MAX, все эти строки будут сведены в одну агрегированную строку. Этот эффект сжатия мог бы возникнуть и для других агрегатных функций, таких как MIN, SUM, GROUP_CONCAT и друзей (см .: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html).. Вы также можете применять определенные группировки, используя конструкцию GROUP BY, но если вы Если функция агрегата просто объединит все строки в одну строку (но это объединение происходит после применения условия WHERE, поэтому агрегируются только отфильтрованные строки)

Теперь, из-за этого уплотняющего или «уменьшающего» эффекта агрегатных функций, существует некоторый способ сделать одно значение из множества значений. Для MAX таким способом является перечисление только максимального значения, найденного для всех экземпляров выражения, которое вы передали в качестве аргумента MAX. Но другие ваши столбцы не имеют такой агрегатной функции. Для большинства продуктов баз данных появление как неагрегированных, так и агрегированных столбцов в списке SELECT будет ошибкой. Но MySQL ведет себя неправильно / по-разному и возвращает только одно из доступных значений для каждого неагрегированного выражения, указанного в бите SELECT. Какое значение имеет значение до mysql - вы не можете полагаться на какой-либо конкретный алгоритм.

Во многих случаях люди хотят что-то сделать с «любой строкой, которая имеет максимальное значение», иными словами, найти строку, которая имеет в качестве значения максимальное значение, но использовать другие столбцы из этой строки без агрегирования. Решение, предоставленное middaparka, делает это, и есть и другие пути для достижения этого (Google для MySQL по группам максимум). Для получения более общей информации о агрегатных функциях и связанных с ними предложениях GROUP BY вы можете взглянуть на -shameless selfplug- моя статья здесь: http://rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html

11 голосов
/ 17 января 2010

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

SELECT * FROM table_name ORDER BY score DESC LIMIT 1
1 голос
/ 17 января 2010

Ваш запрос работает, как задумано: в нем перечислены пользователи и самый высокий общий балл.

Чтобы получить пользователя с наибольшим количеством очков, вы можете использовать

select user, game, score, timestamp from scores ORDER by score DESC limit 1
...