简体   繁体   中英

How do I use MAX() to return the row that has the max value?

I have table orders with fields id , customer_id and amt :

SQL Fiddle

And I want get customer_id with the largest amt and value of this amt .

I made the query:

SELECT customer_id, MAX(amt) FROM orders;

But the result of this query contained an incorrect value of customer_id .

Then I built such the query:

SELECT customer_id, MAX(amt) AS maximum FROM orders GROUP BY customer_id ORDER BY maximum DESC LIMIT 1;

and got the correct result.

But I do not understand why my first query not worked properly . What am I doing wrong?

And is it possible to change my second query to obtain the necessary information to me in a simpler and competent way?

MySQL will allow you to leave GROUP BY off of a query, thus returning the MAX(amt) in the entire table with an arbitrary customer_id . Most other RDBMS require the GROUP BY clause when using an aggregate.

I don't see anything wrong with your 2nd query -- there are other ways to do it, but yours will work fine.

Some versions of SQL give you a warning or error when you select a field, have an aggregate operator like MAX or SUM , and the field you are selecting does not appear in GROUP BY .

You need a more complicated query to fetch the customer_id corresponding to the max amt. Unfortunately SQL is not as naive as you think. Once such way to do this is:

select customer_id from orders where amt = ( select max(amt) from orders);

Although a solution using joins is likely more performant.

To understand why what you were trying to do doesn't make sense, replace MAX with SUM . From the stance of how aggregate operators are interpreted, it's a mere coincidence that MAX returns something that corresponds to an actual row. SUM does not have this property, for instance.

Practically your first query can be seen as if it were GROUP BY-ed into a big single group. Also, MySQL is free to choose each output value from different source rows from the same group.

http://dev.mysql.com/doc/refman/5.7/en/group-by-extensions.html

MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values within each group the server chooses.

The problem with MAX() is that it will select the highest value of that specified field, considering the specified field alone. The other values in the same row are not considered or given preference for the result at any degree. MySQL will usually return whatever value is the first row of the GROUP (in this case the GROUP is composed by the entire table sinse no group was specified), dropping the information of the other rows during the agregation.

To solve this, you could do that:

SELECT customer_id, amt FROM orders ORDER BY amt DESC LIMIT 1

It should return you the customer_id and the highest amt while preserving the relation between both, because no agregation was made.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM