Question

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 :)

Was it helpful?

Solution

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;

OTHER TIPS

Try with the following:

(SELECT * FROM test1 t WHERE t.rank > (SELECT rank FROM test1 t2 WHERE id=ID)+0 ORDER BY rank LIMIT 0,N)
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)
ORDER BY rank
LIMIT 0,N

See the manual for more insight.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top