Distinct values of an SQL Table - mysql

I have this table
and I want the 10 distinct rows with the highest score ordered descending.
So I tried
SELECT * FROM `highscores` GROUP BY userID ORDER BY score DESC LIMIT 10 ;
which is not correct because it returns:
Then I tried:
SELECT distinct(userID),userName,userLastname,score FROMhighscoresORDER BY score DESC ;
which is not correct too, because it doesn't really returns distinct rows based on userID.
And this is the result that I want:
I want to keep the highest score of each player(different userID) for the 10 first players. Any idea how can I do that?

SELECT a.*
FROM highscore a
INNER JOIN
(
SELECT userID, MAX(score) score
FROM highscore
GROUP BY userID
) b ON a.userID = b.userID
AND a.score = b.score
ORDER BY score DESC
LIMIT 10
this does not handle ties, though.

In MySQL you can use the DISTINCT operator with more than one column. The combination of all columns will be used to define the uniqueness of the row in the result set.
For example, to get the unique combination of city and state from the customers table, you use the following query:
SELECT DISTINCT state, city
FROM customers
WHERE state IS NOT NULL
ORDER BY state, city

Try this:
SELECT userID,userName,userLastname, MAX(score) as score
FROM highscores
WHERE userID in (
SELECT distinct userID FROM highscores )
ORDER BY score DESC
LIMIT 10;

Based on your question update:
SELECT h1.* FROM highscores h1
LEFT JOIN highscores h2 ON h1.userId = h2.userId and h1.score < h2.score
WHERE h2.score IS NULL
ORDER BY h1.score DESC
LIMIT 10
A different approach would be:
SELECT h1.* FROM highscores h1
JOIN (
SELECT userId, max(score) maxScore FROM highscores
GROUP BY userId
) h2 ON h1.userId = h2.userId and h1.score = h2.maxScore
ORDER BY h1.score DESC
LIMIT 10

The right query is:
SELECT userName, userLastname, userID, MAX( score )
FROM `highscores`
GROUP BY userID
ORDER BY MAX( score ) DESC
LIMIT 10
Thanks to EddieJamsession's comment.

Related

How do I make a sql sentence to do order by before distinct?

For example, I have this order table, and it has columns: order_id, user_id, create_time, city_id.
Now I want to get the entry of an user's most recent order so basically what I want to do is:
select distinct(order.user_id), city_id
from order
where city_id != 0
order by create_time desc
But as far as I know distinct will run before order by, which means there's already only one user_id left for each user before it reaches order by, so what do I do to make order by run first?
Have a sub-query that returns each user's most recent create_time. JOIN with that result.
select o1.user_id, o1.city_id
from order o1
join (select user_id, max(create_time) as newest_create_time
from order
where city_id != 0
group by user_id) o2
on o1.user_id = o2.user_id and o1.create_time = o2.newest_create_time
where o1.city_id != 0

MySQL - if row is duplicate, return only the first one

I have a MySQL table "results" which has the following fields:
id (PK, AI), user_id (FK), date, score, time
I want to be able to query this table so that it sorts and returns the fields in order of score (descending order) followed by time (ascending order). So something like:
SELECT * FROM results ORDER BY score DESC, time ASC.
However, after this sorting, if more than one row has the same user_id, I only want to include the highest row.
How would I do this?
You can do this with not exists:
SELECT *
FROM results r
WHERE NOT EXISTS (select 1 from results r2 where r2.user_id = r.user_id and r2.id > r.id)
ORDER BY score DESC;
This will work best with an index on results(user_id, id).
My suggestion: SELECT user_id, max(score), time FROM results GROUP BY user_id ORDER BY score DESC;
Select id and highest score per user_id via max() and Group By. Then order the records by score descending.
EDIT: If you need the time for the user-score and there is only one entry with the same score you can use a subselect to get this time:
SELECT user_id, max(score), (
SELECT max(time)
FROM results AS r2
WHERE r2.user_id = r1.user_id
AND r2.score = max(r1.score)
) AS time
FROM results AS r1
GROUP BY user_id
ORDER BY score DESC;
I've managed to get something working at the moment.
SELECT user_id, score, time
FROM results T
WHERE T.score = (
SELECT MAX(T2.score)
FROM results T2
WHERE T2.user_id = T.user_id
)
ORDER BY score DESC, time ASC;

SQL: select all the rows from the two userid's with great number of rows

I would like to get all the rows from the two users with the greatest number of rows, that is, the two users with the greatest activity in a log table.
I have only found next solution: first, get the number of rows for every user, an limit it to 2:
SELECT userid, count(*) AS n_of_rows FROM my_table GROUP BY userid LIMIT 2;
Then, from the source code I'm querying the database (Python for example), query the database to get the rows of each user:
SELECT * FROM my_table where userid = $userid
Is it the best/elegant solution, taking into account SQL language itself and database performance?
Thanks!
I think what you're looking for is something like
select * from my_table where userid in
(select userid from my_table
group by userid
order by count(*) desc
limit 2)
To get the rows and keep the order, use a join with aggregation:
select t.*
from my_table t join
(select userid, count(*) as cnt
from my_table
group by userid
order by count(*) desc
limit 2
) top2
on t.userid = top2.userid
order by top2.cnt desc, userid;
Try this:
SELECT TOP 2 userid, count(*) AS n_of_rows
FROM my_table
GROUP BY userid
ORDER BY count(*) desc

MySQL select SUM with LIMIT AND WHERE

I'm trying to select the SUM of a few values with a limit of 2. I've seen a couple of example of this (9877872) but have been unable to get it working. I have
SELECT SUM(points)
FROM
(SELECT points FROM user_table
WHERE city=1 AND group =5)
AS min_points ORDER BY points DESC LIMIT 2
However the limit clause at the end of the query does not seem to be executed and I just get the sum of all the users in the table...
Would anyone know what I'm doing wrong...?
Try this
SELECT SUM(points)
FROM
(SELECT points FROM user_table
WHERE city=1 AND group =5 ORDER BY points DESC LIMIT 2) AS t1

most occuring show in mysql table

I have the following data set.
How would the query look if wanted the most occuring show on top and limit the result for 20 shows?
EDIT
I have searched on the web for this and i need to use the GROUP BY method from sql. but when i make the query
SELECT `show` FROM fans GROUP BY `show` LIMIT 20
i do not get the desired result.
SELECT a.*, b.TotalCount
FROM TableName a
INNER JOIN
(
SELECT c.show, COUNT(*) totalCount
FROM TableName c
GROUP BY c.show
) b ON a.show = b.show
ORDER BY b.TotalCount DESC
LIMIT 20
if you want to list one record for every show, you can simply use GROUP BY
SELECT a.show, COUNT(*) TotalCount
FROM TableName a
GROUP BY a.Show
ORDER BY TotalCount DESC
LIMIT 20