是否有更有效的方法来获取每组的前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名,但足以显示我在做什么。
选项(我正在考虑):
备注:
我意识到我可能没有提供足够的细节,所以让我知道你需要什么。我只是在寻找解决这个问题的一般方法。上面的查询大约需要5分钟才能在30,000行的表上运行。这不是什么大问题,因为查询每小时只运行一次。
将查询分成较小的部分可能会运行得更快,但表格会被写入很多,因此查询会被锁定。