Django ORM:将表连接到自身并聚合
我的Django应用程序UserMonthCores中有一个表,每个用户每个月都有一个“分数”。看来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
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可能仍然是实现这一点的最佳方法。