I'm building a "Top 3 Scores" Leaderboard. I want to display the top three scores, drawing the max per person, but I don't want to limit 3, because I want to display anyone that has the top 3 scores. So for example, with the data below,
+----+-----+
|Name|Score|
+----+-----+
|Matt| 17|
|Mark| 29|
|Luke| 28|
|John| 29|
|Paul| 27|
|Matt| 29|
|Mark| 22|
+----+-----+
I want to display:
+------+-----+
|Name |Score|
+------+-----+
|1.Matt| 30|
|2.Mark| 29|
|2.John| 29|
|3.Luke| 28|
+------+-----+
My first thought is to extract the max for everyone, and then stop displaying after the score changes (using PHP).
select name, max(score)
from SCORES
group by name
order by name
Is there any way to do this directly in SQL?
To select multiple values, you can use where clause with OR and IN operator.
SELECT name, score
FROM SCORES
JOIN (SELECT distinct score score3
FROM scores
ORDER BY score DESC
LIMIT 2, 1) x
ON score >= score3
ORDER by score DESC
FIDDLE
SELECT name,score
FROM SCORES
WHERE score in (
SELECT distinct s.score
FROM SCORES as s
ORDER BY s.score desc
LIMIT 3)
)
ORDER BY score
SELECT Name, MAX(Score) Score
FROM TableName a
WHERE EXISTS
(
SELECT 1
FROM TableName b
WHERE a.Score = b.Score
GROUP BY Score
ORDER BY Score DESC
LIMIT 3
)
GROUP BY Name
ORDER BY Score DESC
OUTPUT based on the records given above
╔══════╦═══════╗
║ NAME ║ SCORE ║
╠══════╬═══════╣
║ Mark ║ 29 ║
║ John ║ 29 ║
║ Matt ║ 29 ║
║ Luke ║ 28 ║
║ Paul ║ 27 ║
╚══════╩═══════╝
this will give the top three scores, regardless of ties.
SELECT score
FROM mytable
group by score
ORDER BY score
DESC
LIMIT 3
now get the third score.
SELECT MIN(score') FROM (SELECT
scoreFROM
mytablegroup by score
ORDER BY
score` DESC
LIMIT 3) as top3
finally get everything equal or above the third score
SELECT * FROM mytable
WHERE score' >=
(SELECT MIN(
score') FROM
(SELECT score
FROM mtyable
group by score'
ORDER BY
score` DESC
LIMIT 3) as top3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With