2010-01-17 3 views
2

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

 
    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, но остальные столбцы, которые возвращаются, не из той же самой строки.

ответ

18

Вы используете 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 вы можете взглянуть на бескомпромиссную самозарядную статью здесь: http://rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html

+0

Вау, какой глубокий ответ. +1 –

+0

спасибо Пекке, очень благодарен :) –

+0

удивительный ответ! именно эту информацию мне нужно было понять, как все работает. спасибо – ufk

9

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

SELECT * FROM table_name ORDER BY score DESC LIMIT 1 
+0

Ударьте меня в это. +1 –

+1

@Pekka - редкая победа. ;-) –

1

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

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

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

Ну, он перечисляет максимальный балл, но я не чувствую, что другие столбцы перечисляют пользователей. скорее, для каждого столбца выбрано какое-то значение - вы не можете полагаться на то, что они из одной и той же исходной строки. –

Смежные вопросы