I have a (game) leaderboard table which contains a rank which is updated by another query. It is centered around the ID - when I query the table I ideally want to get back N records. So I have done a UNION on the records both with the limit N/2 like so:
(SELECT * FROM test1 t WHERE t.rank > (SELECT rank FROM test1 t2 WHERE id=ID)+0 ORDER BY rank LIMIT 0, N/2)
UNION ALL
(SELECT * FROM test1 t WHERE t.rank <= (SELECT rank FROM test1 t2 WHERE id=ID)+0 ORDER BY rank desc LIMIT 0, N/2) ORDER BY rank
Although this does not quite work when at the top of the leaderboard, it will only return the lower N/2. Is there a way to ensure that it will always return the N records? I did think that you could purposefully get more records than required and then trim the records off which you don't need. Although I do not know how to do this with a query!
Any help appreciated :)
You can do this with a clever use of order by
and limit
:
SELECT t.*
FROM test1 t cross join
(SELECT rank FROM test1 t2 WHERE id = @ID) as theone
ORDER BY ABS(theone.rank - t.rank)
LIMIT N;
You probably then want these back in rank order:
SELECT t.*
FROM (SELECT t.*
FROM test1 t cross join
(SELECT rank FROM test1 t2 WHERE id = @ID) as theone
ORDER BY ABS(theone.rank - t.rank)
LIMIT N
) t
ORDER BY t.rank;