Search code examples
mysqlsqlmysql-error-1111

querying for user's ranking in one-to-many tables


I am trying to write a query to find the score rank of a user's games. I need it to take in a user id and then return that user's relative ranking to other user's scores. There is a user and a game table. The game table has a userId field with a one-to-many relationship.

Sample table:

users:
id freebee
1 10
2 13

games:
userId score
1 15
1 20
2 10
1 15

passing $id 1 into this function should return the value 1, as user 1 currently has the highest score. Likewise, user 2 would return 2.

Currently this is what I have:

SELECT outerU.id, (

SELECT COUNT( * )  
FROM users userI, games gameI  
WHERE userI.id = gameI.userId  
AND userO.id = gameO.userId  
AND (  
   userI.freebee + SUM(gameI.score)  
   ) >= ( userO.freebee + SUM(gameO.score) )  
) AS rank  
FROM users userO,  
games gameO  
WHERE id = $id

Which is giving me an "invalid use of group function" error. Any ideas?


Solution

  • SELECT u.id,total_score,
     ( SELECT COUNT(*) FROM
        (SELECT u1.id, (IFNULL(u1.freebee,0)+ IFNULL(SUM(score),0)) as total_score
         FROM users u1
         LEFT JOIN games g ON (g.userId = u1.id)
         GROUP BY u1.id
        )x1
       WHERE x1.total_score > x.total_score
     )+1 as rank,
    
    ( SELECT COUNT(DISTINCT total_score) FROM
        (SELECT u1.id, (IFNULL(u1.freebee,0)+ IFNULL(SUM(score),0)) as total_score
         FROM users u1
         LEFT JOIN games g ON (g.userId_Id = u1.id)
         GROUP BY u1.id
        )x1
       WHERE x1.total_score > x.total_score
     )+1 as dns_rank
    
     FROM users u
    
     LEFT JOIN
      ( SELECT u1.id, (IFNULL(u1.freebee,0)+ IFNULL(SUM(score),0)) as total_score
        FROM users u1
        LEFT JOIN games g ON (g.userId = u1.id)
        GROUP BY u1.id
      )x ON (x.id = u.id)
    

    rank - (normal rank - e.g. - 1,2,2,4,5), dns_rank - dense rank (1,2,2,3,4). Column total_score - just for debugging...