简体   繁体   中英

Get row with max(column)

Whenever I use the max function I somehow lose all the connection to my other values, so that the row that is printed later doesn't correlate with the column that I ran max on anymore.

So my table is:

user col1 col2 col3
1    1    2    3
1    3    4    5
2    2    3    1
3    1    1    3
3    2    4    6
4    5    1    5

So if I run

select user, col1, col2, max(col3) as col3
from table
group by user
order by user;

I would get

user col1 col2 col3
1    1    2    5
2    2    3    1
3    1    1    6
4    5    1    5

So the max value of col3 is correct, but it doesn't get the correct row of that value.

What I want is to get the max value of a column and return that row for each user. If there are multiple max values that it should return all users, even if it has same user id.

Other databases (eg MS SQL Server) doesn't let you mix aggergated values with non-aggregated values, just because you would get the wrong result.

So, if you want non-aggregated values from the record where the maximum value was, join against the table again:

select x.user, y.col1, y.col2, x.col3
from (
  select user, max(col3) as col3
  from table
  group by user
) x
inner join table y on y.user = x.user and y.col3 = x.col3
order by x.user

This may see crazy but it should work for you

SELECT B.* FROM
(
    SELECT user,MAX(col3) col3
    FROM mytable GROUP BY user
) A
INNER JOIN mytable B
USING (user,col3) ORDER BY user,col3;

Here is the sample data:

mysql> DROP DATABASE IF EXISTS terry;
Query OK, 1 row affected (0.06 sec)

mysql> CREATE DATABASE terry;
Query OK, 1 row affected (0.00 sec)

mysql> USE terry
Database changed
mysql> CREATE TABLE mytable
    -> (user INT,col1 INT,col2 INT,col3 int,
    -> key (user,col3));
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO mytable VALUES
    -> (1,    1,    2,    3),(1,    3,    4,    5),
    -> (2,    2,    3,    1),(3,    1,    1,    3),
    -> (3,    2,    4,    6),(4,    5,    1,    5);
Query OK, 6 rows affected (0.07 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM mytable;
+------+------+------+------+
| user | col1 | col2 | col3 |
+------+------+------+------+
|    1 |    1 |    2 |    3 |
|    1 |    3 |    4 |    5 |
|    2 |    2 |    3 |    1 |
|    3 |    1 |    1 |    3 |
|    3 |    2 |    4 |    6 |
|    4 |    5 |    1 |    5 |
+------+------+------+------+
6 rows in set (0.00 sec)

Here is the output of the query:

mysql> SELECT B.* FROM
    -> (
    ->     SELECT user,MAX(col3) col3
    ->     FROM mytable GROUP BY user
    -> ) A
    -> INNER JOIN mytable B
    -> USING (user,col3) ORDER BY user,col3;
+------+------+------+------+
| user | col1 | col2 | col3 |
+------+------+------+------+
|    1 |    3 |    4 |    5 |
|    2 |    2 |    3 |    1 |
|    3 |    2 |    4 |    6 |
|    4 |    5 |    1 |    5 |
+------+------+------+------+
4 rows in set (0.02 sec)

mysql>

This output would be correct because for every user in the sample data you gave, there is only one occurrence of a max value for col3. If two rows for a give user had the same col3 as a max value, they both should appear.

To illustrate this, let's add another row with user=3 and col3=6;

mysql> INSERT INTO mytable VALUES (3,8,9,6);
Query OK, 1 row affected (0.10 sec)

mysql> SELECT B.* FROM
    -> (
    ->     SELECT user,MAX(col3) col3
    ->     FROM mytable GROUP BY user
    -> ) A
    -> INNER JOIN mytable B
    -> USING (user,col3) ORDER BY user,col3;
+------+------+------+------+
| user | col1 | col2 | col3 |
+------+------+------+------+
|    1 |    3 |    4 |    5 |
|    2 |    2 |    3 |    1 |
|    3 |    2 |    4 |    6 |
|    3 |    8 |    9 |    6 |
|    4 |    5 |    1 |    5 |
+------+------+------+------+
5 rows in set (0.00 sec)

mysql>

Give it a Try !!!

You need to eliminate the col1 and col2 from the query, since they make the rows unique. Try

SELECT user, max(col3) AS col3 FROM table GROUP BY user ORDER BY user;
select t1.user, t1.col1, t1.col2, t1.col3
from table1 t1
where not exists(select * from table1 t2
                 where t1.user = t2.user
                   and t1.col3 < t2.col3)

If there are several rows for one user with the same (maximum) col3 value, then all rows with this value for this user will be returned.

In your query, you select the max for each row and that is selected as a column. You want to know what's the max and use that as a restriction to select the rows with that value.


Assuming you want the max from col3 , you can do it like this:

select t.user,
       t.col1,
       t.col2,
       t.col3
from tablename t
join (
      select max(col3) as 'maximum'
      from tablename
     ) aux on aux.maximum = t.col3

The aux join selects the max value of col3 and then you join with your table using col3 as the restriction.

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