Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL ORDER BY multiple column ASC and DESC

I have 2 MYSQL tables, users and scores. Detail:

  • users table:

enter image description here

  • scores table:

enter image description here

My intention is get 20 users list that have point field sort DESC (descending) combine avg_time field sort ASC (ascending). I use the query:

SELECT users.username, scores.point, scores.avg_time FROM scores, users WHERE scores.user_id = users.id GROUP BY users.username ORDER BY scores.point DESC, scores.avg_time LIMIT 0, 20 

The result is:

enter image description here

The result is wrong because the first line is exactly point = 100 and avg_time = 60.

My desired result is:

username    point    avg_time demo123      100        60 demo123456   100       100 demo         90        120 

I tried many times with different queries but the result is still wrong. Could you give me some solutions?

Thanks in advance!

like image 359
Tan Viet Avatar asked Dec 04 '12 01:12

Tan Viet


People also ask

Can I use ORDER BY ASC and DESC in same query?

Several times we may have to use ORDER BY ASC and ORDER BY DESC in same SQL query on different columns. Here is an example of using ORDER BY DESC on one column. Here is an example of using ORDER BY ASC on one column. SELECT * FROM mytable ORDER BY column1 ASC, column2.

How do I sort multiple columns in MySQL?

Summary. Use the ORDER BY clause to sort the result set by one or more columns. Use the ASC option to sort the result set in ascending order and the DESC option to sort the result set in descending order. The ORDER BY clause is evaluated after the FROM and SELECT clauses.

How do I sort multiple columns in ascending order in SQL?

Syntax: SELECT * FROM table_name ORDER BY column_name; For Multiple column order, add the name of the column by which you'd like to sort records first. The column that is entered at first place will get sorted first and likewise.

How do I sort by both ASC and DESC in SQL?

The ORDER BY keyword is used to sort the result-set in ascending or descending order. The ORDER BY keyword sorts the records in ascending order by default. To sort the records in descending order, use the DESC keyword.


2 Answers

Ok, I THINK I understand what you want now, and let me clarify to confirm before the query. You want 1 record for each user. For each user, you want their BEST POINTS score record. Of the best points per user, you want the one with the best average time. Once you have all users "best" values, you want the final results sorted with best points first... Almost like ranking of a competition.

So now the query. If the above statement is accurate, you need to start with getting the best point/average time per person and assigning a "Rank" to that entry. This is easily done using MySQL @ variables. Then, just include a HAVING clause to only keep those records ranked 1 for each person. Finally apply the order by of best points and shortest average time.

select       U.UserName,       PreSortedPerUser.Point,       PreSortedPerUser.Avg_Time,       @UserRank := if( @lastUserID = PreSortedPerUser.User_ID, @UserRank +1, 1 ) FinalRank,       @lastUserID := PreSortedPerUser.User_ID    from       ( select               S.user_id,               S.point,               S.avg_time            from               Scores S            order by               S.user_id,               S.point DESC,               S.Avg_Time ) PreSortedPerUser          JOIN Users U             on PreSortedPerUser.user_ID = U.ID,       ( select @lastUserID := 0,                @UserRank := 0 ) sqlvars     having       FinalRank = 1    order by       Point Desc,       Avg_Time 

Results as handled by SQLFiddle

Note, due to the inline @variables needed to get the answer, there are the two extra columns at the end of each row. These are just "left-over" and can be ignored in any actual output presentation you are trying to do... OR, you can wrap the entire thing above one more level to just get the few columns you want like

select        PQ.UserName,       PQ.Point,       PQ.Avg_Time    from       ( entire query above pasted here ) as PQ 
like image 197
DRapp Avatar answered Sep 28 '22 15:09

DRapp


i think u miss understand about table relation..

users : scores = 1 : *

just join is not a solution.

is this your intention?

SELECT users.username, avg(scores.point), avg(scores.avg_time) FROM scores, users WHERE scores.user_id = users.id GROUP BY users.username ORDER BY avg(scores.point) DESC, avg(scores.avg_time) LIMIT 0, 20 

(this query to get each users average point and average avg_time by desc point, asc )avg_time

if you want to get each scores ranking? use left outer join

SELECT users.username, scores.point, scores.avg_time FROM scores left outer join users on scores.user_id = users.id ORDER BY scores.point DESC, scores.avg_time LIMIT 0, 20 
like image 39
namxee Avatar answered Sep 28 '22 15:09

namxee