Reputation: 141
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.
Upvotes: 3
Views: 3032
Reputation: 700362
Other databases (e.g. 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
Upvotes: 4
Reputation: 44343
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 !!!
Upvotes: 2
Reputation: 391
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.
Upvotes: 1
Reputation: 66697
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.
Upvotes: 0
Reputation: 4192
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;
Upvotes: 1