我有一种情况需要在区域排行榜中检索当前用户的位置。
我的表看起来像这样:
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个用户
答案 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