排行榜中的“我的”位置

时间:2014-03-06 13:12:46

标签: php mysql

我有一种情况需要在区域排行榜中检索当前用户的位置。

我的表看起来像这样:

Users
id | city | ...


Collected_Items
id | user_id | value | ...


Achievements
id | user_id | value | ...

简单地说,我想检索排行榜中的位置以及每个value的{​​{1}}的总和以及每个collected_item的总和{{ 1}}。等值总值可以相等或者基于收集的时间戳(首先收集胜利)

到目前为止我有这个:(改编自SO answer

value

产生的结果如

achievement

这很棒,但我需要包含成就,获取每个用户的位置以及SELECT user_id, user_points FROM ( SELECT user_id, SUM(collected_items.value) AS 'user_points' FROM collected_items GROUP BY user_id ORDER BY SUM(collected_items.value) DESC ) AS T1 GROUP BY T1.user_points ORDER BY T1.user_points DESC 查询(用户只查看他们自己城市中的排行榜)

我的理想结果如下:

Results
user_id | user_points
2       | 61
1       | 1

我如何改变上述内容以产生预期效果? (我也愿意使用PHP操作)

备注(出于速度目的):
   - 有101件收藏品    - 有101个成就
   - 将有多达250,000个用户

3 个答案:

答案 0 :(得分:3)

你可以使用像

这样的东西
SELECT
  @i:=@i+1 AS rank,
  sub.*
FROM
  (SELECT 
    user_id, 
    user_points
    FROM (
      SELECT 
        collected_items.user_id,
        SUM(collected_items.value)+SUM(achievements.value) AS user_points
        FROM 
          collected_items
            INNER JOIN achievements ON collected_items.user_id=achievements.user_id
        GROUP BY collected_items.user_id
        ORDER BY user_points DESC
    ) AS T1
    GROUP BY T1.user_points
    ORDER BY T1.user_points DESC
  ) AS sub
  CROSS JOIN (SELECT @i:=0) AS init

答案 1 :(得分:1)

提到this post,我建议:

SELECT 
    @s:=@s+1,
    user_id, 
    user_points
    FROM (SELECT @s:= 0),(
      SELECT 
        user_id,
        SUM(collected_items.value) AS 'user_points'
        FROM collected_items
        GROUP BY user_id
        ORDER BY SUM(collected_items.value) DESC
    ) AS T1
    GROUP BY T1.user_points
    ORDER BY T1.user_points DESC

答案 2 :(得分:1)

要获取其他字段,您只需INNER JOIN再次针对user表,然后,您必须由字段用户订购:

SELECT 
u.id, 
T2.*,
@i:=@i+1 AS rank

-- ... additional fields

FROM (
  SELECT * FROM (
      SELECT 
        user_id,
        SUM(collected_items.value) AS 'user_points'
        FROM collected_items
        GROUP BY user_id
        ORDER BY SUM(collected_items.value) DESC
    ) AS T1
    GROUP BY T1.user_points, T1.      
 ) T2
 INNER JOIN users u
 ON T2.user_id = u.id

 -- ... More inner joins to get more data...

 ORDER BY T2.user_points DESC