Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ORDER BY after GROUP BY does not working

Tags:

sql

mysql

SELECT * 
FROM (SELECT id, user, MAX(score) FROM table_1 GROUP BY user) AS sub
ORDER BY 'sub.score' ASC;

This SQL query should select from a table only a score per user, and for accuracy, the highest.

The table structure is this:

+-----------------------+
| id | score | username |
+-----------------------+
| 1  |    15 |     mike |
| 2  |    23 |     tom  |
| 3  |    16 |     mike |
| 4  |    22 |     jack |

etc..

The result should be like:

3 mike 16
2 tom  23
4 jack 22

And then reordered:

3 mike 16
4 jack 22
2 tom  23

But the query does not reorder the subquery by score. How to do so?

like image 556
Northumber Avatar asked Oct 30 '16 22:10

Northumber


People also ask

Can you use ORDER BY after GROUP BY?

When combining the Group By and Order By clauses, it is important to bear in mind that, in terms of placement within a SELECT statement: The GROUP BY clause is placed after the WHERE clause. The GROUP BY clause is placed before the ORDER BY clause.

WHERE do I go after GROUP BY?

GROUP BY clause is used with the SELECT statement. In the query, GROUP BY clause is placed after the WHERE clause. In the query, GROUP BY clause is placed before ORDER BY clause if used any.

Does GROUP BY automatically order?

group by does not order the data neccessarily. A DB is designed to grab the data as fast as possible and only sort if necessary. So add the order by if you need a guaranteed order.

Can we use ORDER BY without using GROUP BY?

Key Differences between GROUP BY and ORDER BY The Group By clause is used to group data based on the same value in a specific column. The ORDER BY clause, on the other hand, sorts the result and shows it in ascending or descending order. It is mandatory to use the aggregate function to use the Group By.


1 Answers

Let's look at what you are doing step by step:

SELECT id, user, MAX(score) FROM table_1 GROUP BY user

Here you are grouping by user name, so you get one result row per user name. In this result row you select the user name, the maximum score found for this user name (which is 16 for 'mike') and one of the IDs found for the user name (which can be 1 or 3 for 'mike', the DBMS is free to choose one). This is probably not what you want.

SELECT * FROM (...) AS sub  ORDER BY 'sub.score' ASC;

'sub.score' is a string (single quotes). You want to order by the max score from your subquery instead. So first give the max(score) a name, e.g. max(score) as max_score, and then access that: ORDER BY sub.max_score ASC.

Anyway, if you want the record with the maximum score for a user name (so as to get the according ID, too), you could look for records for which not exists a record with the same user name and a higher score. Sorting is easy then: as there is no aggregation, you simply order by score:

select * from table_1 t1 where not exists 
  (select * from table_1 higher where higher.name = t1.name and higher.score > t1.score)
order by score;
like image 138
Thorsten Kettner Avatar answered Oct 13 '22 04:10

Thorsten Kettner