我有积分表:
=========================================== FIELD : TYPE =========================================== id int(11) user_id int(11) value int(11) type enum('add','subtract') timestamp int(11) ===========================================
此表基本上存储用户点的记录。
现在我的问题是:如何获得总积分最高的前10位用户?
注意:我被告知要更改我的架构 - 删除'type'字段并为'value'字段添加正值和负值。我只是想知道我是否可以使用当前架构实现所需的查询。
提前致谢
答案 0 :(得分:6)
我会尝试这样的事情:
SELECT
user_id,
SUM( IF(`type`='add',+1,-1) * `value`) AS user_points
FROM Points
GROUP BY user_id
ORDER BY SUM( IF(`type`='add',+1,-1) * `value`) DESC
LIMIT 10
似乎有效:http://sqlfiddle.com/#!2/dd207/1
替代方案,也许更快,也许不是,诀窍是从内部查询移出SUM(IF())
部分:
http://sqlfiddle.com/#!2/dd207/9
SELECT
user_id,
SUM( IF(`type`='add',+1,-1) * `valuesum`)
FROM (
SELECT
user_id,
`type`,
SUM(`value`) AS `valuesum`
FROM Points
GROUP BY user_id, `type`
) AS p
GROUP BY p.user_id
ORDER BY SUM( IF(`type`='add',+1,-1) * `valuesum`) DESC
LIMIT 10
可能两个解决方案都必须进行全表扫描以总结所有内容,因此这种情况可能是一些明智的非规范化(例如,在另一个表中收集每个用户的总和)的好选择。