Django ORM:将表连接到自身并聚合

Django ORM:将表连接到自身并聚合,django,orm,self-join,Django,Orm,Self Join,我的Django应用程序UserMonthCores中有一个表,每个用户每个月都有一个“分数”。看来 userid | month | year | score -------+-------+------+------ sil | 9 | 2014 | 20 sil | 8 | 2014 | 20 sil | 7 | 2014 | 20 other | 9 | 2014 | 100 other | 8 | 2014 | 1 mon

我的Django应用程序UserMonthCores中有一个表,每个用户每个月都有一个“分数”。看来

userid | month | year | score
-------+-------+------+------
sil    | 9     | 2014 | 20
sil    | 8     | 2014 | 20
sil    | 7     | 2014 | 20
other  | 9     | 2014 | 100
other  | 8     | 2014 | 1
month | year | rank
------+------+-----
9       2014   2       # in second position behind user "other" who scored 100
8       2014   1       # in first position ahead user "other" who scored 1
7       2014   1       # in first position because no-one else scored anything!
我想计算出一个特定用户每月在排名表中的位置。因此,在上面,如果我要求每月为用户“sil”排名,我应该得到如下响应

userid | month | year | score
-------+-------+------+------
sil    | 9     | 2014 | 20
sil    | 8     | 2014 | 20
sil    | 7     | 2014 | 20
other  | 9     | 2014 | 100
other  | 8     | 2014 | 1
month | year | rank
------+------+-----
9       2014   2       # in second position behind user "other" who scored 100
8       2014   1       # in first position ahead user "other" who scored 1
7       2014   1       # in first position because no-one else scored anything!
在SQL中,我这样做的方法是在月/年将表连接到自身,并选择第二个表用于特定用户且第一个表的分数大于第二个表的行(按月/年分组),然后选择每月/年的行数。即:

select u1.month,u1.year,count(*) from UserMonthScores u1 
  inner join UserMonthScores u2 
  on u1.month=u2.month and u1.year=u2.year 
  and u2.userid = 'sil' and u1.score >= u2.score 
  group by u1.year, u1.month;

效果很好。但是,我不明白如何使用Django ORM进行此查询。关于将表连接到表本身,还有其他问题,但它们似乎没有涵盖这个用例。

您需要使用ORM吗?如果不是,您可以将SQL查询用作一个查询。如果RDMS支持,我还建议您将SQL更改为使用
RANK()
窗口函数。我不需要使用ORM,事实上,我已经通过使用上面的原始SQL查询完成了这一点,但如果可能,最好使用ORM,因为这样我就不会回避它所做的好事。(我不知道RANK——谢谢!——但我认为sqlite无论如何都不支持它。)我认为ORM不支持窗口功能,但我只能找到。尽管如此,我认为您的原始SQL可能仍然是实现这一点的最佳方法。