MySQL top X结果在每个组内

时间:2013-07-17 06:03:37

标签: mysql optimization

是否有更有效的方法来获取每组的前X个结果?

您可以忽略sqlfiddle中未在查询中使用的任何字段。

查询:

SET @num := 0, @item_id := '';
SELECT `item_id`, `user_id`, total_hoarded FROM (
        SELECT `item_id`, `user_id`, total_hoarded,
                @num := IF(@item_id = x.`item_id`, @num + 1, 1) AS ROW_NUMBER,
                @item_id := x.`item_id` AS dummy
        FROM (
                SELECT `item_id`, `user_id`, COUNT(*) AS total_hoarded
                FROM `player_items`
                GROUP BY `item_id`, `user_id`
                ORDER BY `item_id`, total_hoarded DESC
        ) AS x
) AS y WHERE y.ROW_NUMBER <= 10;");

演示:http://sqlfiddle.com/#!2/75bc7/1

查询说明

(从最嵌套的查询开始)它通过item_id和user_id抓取并分组所有行,以便我们可以执行一些聚合函数来计算每个用户拥有的项目数。

然后上一级向每行附加一个row_number,这样最终查询就可以简单地获取小于X的所有行(在这种情况下,每个分组的前10位用户)。

SQLFiddle在样本的大小方面受到限制,因此它只显示两个项目和少数用户的数据。不足以完全填满前10名,但足以显示我在做什么。

选项(我正在考虑)

  • 保持查询不变。
  • 执行标准查询分组并通过PHP循环以获取前10名
  • 其他? (没有想到任何其他人)

备注

我意识到我可能没有提供足够的细节,所以让我知道你需要什么。我只是在寻找解决这个问题的一般方法。上面的查询大约需要5分钟才能在30,000行的表上运行。这不是什么大问题,因为查询每小时只运行一次。

将查询分成较小的部分可能会运行得更快,但表格会被写入很多,因此查询会被锁定。

0 个答案:

没有答案