需要帮助构建SQL SELECT语句以获得“前10 x”

时间:2012-06-22 20:29:51

标签: mysql sql

我有积分表:

===========================================
FIELD           :      TYPE
===========================================
id                 int(11)
user_id            int(11)
value              int(11)
type               enum('add','subtract')
timestamp          int(11)
===========================================

此表基本上存储用户点的记录。

现在我的问题是:如何获得总积分最高的前10位用户?

注意:我被告知要更改我的架构 - 删除'type'字段并为'value'字段添加正值和负值。我只是想知道我是否可以使用当前架构实现所需的查询。

提前致谢

1 个答案:

答案 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

可能两个解决方案都必须进行全表扫描以总结所有内容,因此这种情况可能是一些明智的非规范化(例如,在另一个表中收集每个用户的总和)的好选择。