这里我有两个关注的表:users 和 race_weeks。 User 有很多 race_weeks,race_week 属于 User。因此,user_id 是 race_weeks 表中的一个 fk。
我需要对 race_weeks 表中的字段执行一些具有挑战性的数学运算,以便返回拥有最高积分的用户。
这是我们需要在 race_weeks 表中操作的字段。
races_won (int)
races_lost (int)
races_tied (int)
points_won (int, pos or neg)
recordable_type(varchar, Robots can race, but we're only concerned about type 'User')
为了让您充分理解此处工作的业务逻辑,在一周的时间里,用户可以参加许多比赛。 race_week 记录表示该周用户比赛的汇总结果。如果 races_won、races_lost 或 races_tied 大于 0,则认为用户本周活跃。否则用户不活跃。
因此,为了返回获得最多积分(实际上是 net_points_won)的用户,我们需要在查询中执行以下操作:
计算每个用户的 net_points_won(不是数据库中的字段)。
要计算 net_points_won,您需要 (1000 * count_of_active_weeks) - sum(points__won)。 (为什么是 1000?试想一下,每周都会发现用户有 1000 分来参加比赛。我们想分解我们发现的用户,因为用户一周只能参加一场比赛以获得 100 分,并且是坐在 900 上,我们会歪曲实际获得最多分数的人。)
这个有点令人费解,如果我能进一步澄清,请告诉我。
最佳答案
我认为您的业务逻辑不正确:net_points
应该是该用户赢得的点数减去该用户被发现的点数的总和。
此外,对活跃周的检查应该针对零显式地测试 races_won
、races_lost
和 races_tied
,以便系统有机会当表变大时,在这些列上使用索引。
SELECT user_id
, SUM(points_won) - 1000 * COUNT(*) AS net_points
FROM race_weeks
WHERE recordable_type = 'User'
AND (races_won > 0 OR races_lost > 0 OR races_tied > 0)
GROUP BY user_id
ORDER BY net_points DESC
关于SQL 查询数学体操,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2692795/