我有一个看起来像这样的表:
HorseID RiderID Total
121 1 2
5 1 150
600 1 20
30 2 500
5 3 10
600 3 10
34 3 10
每匹马可能有多个骑手,反之亦然。 '总'指骑手与骑马相结合的事故总数。我想要的是一张表格,其中包含每位骑手的总排名为2的HorseIDs,并进行了重复数据删除。 (即,骑手1的顶级马匹是5匹马,因为他们共同发生了150起事故,而其他骑马1匹的情况则为20和2)。所以我想在这里输出的是:
HorseID
5
600
30
注意当骑手少于2匹马时,应该抓住前1名。当谈到骑手3时,有一个平局,所以它按顺序选择前2名 - 但是,这些已经在列表中,所以没有添加(重复数据删除部分 - 也很乐意在之后的单独步骤中进行重复数据删除,如果这样做& #39;更快)。我不会介意这是否会在平局中抓住第34位(所以我们在列表中有一个额外的马匹),任何解决平局的方法都很好。
这是一个玩具数据集,真正的数据集要大得多,我会抓住每个RiderID的前200名,因此可扩展/高效的解决方案会很棒。
我该怎么做?
答案 0 :(得分:0)
这只是一个稍微修改过的source问题。由于MySQL缺乏分析功能,因此MySQL并不是最好的每组最好的,但你可以这样做:
SELECT DISTINCT HorseID
FROM (SELECT HorseID, RiderID, Total,
@num := IF(@group = RiderID, @num + 1, 1) AS row_number,
@group := RiderID AS group
FROM UnnamedTable
ORDER BY RiderID, Total DESC, HorseID) ranked
WHERE row_number <= 2;
请注意,不处理关系。如果前三匹马的总数为200,那么你仍然只能获得两排。请注意,子查询的ORDER BY中的第三项是HorseID。这只是在结果的情况下使结果具有确定性。您可以通过向IF()
表达式添加一点逻辑来处理关系,并将其从greatest-n-per-group更改为类似ROW_NUMBER()
。但是,如果你想让它像DENSE_RANK()
那样,我认为你需要第三个变量。
我不确定这种情况有多好。