【问题标题】:Django query to fetch top performers for each monthDjango 查询以获取每个月表现最好的人
【发布时间】:2021-09-27 16:10:15
【问题描述】:

我需要获取每个月表现最好的,这是下面的 MySql 查询,它给了我正确的输出。

select id,Name,totalPoints, createdDateTime 
from userdetail
where app=4 and totalPoints in ( select 
max(totalPoints) 
FROM userdetail
where app=4 
group by  month(createdDateTime), year(createdDateTime))
order by totalPoints desc

我是 Django ORM 的新手。我无法编写完成该任务的等效 Django 查询。我已经为这个逻辑苦苦挣扎了 2 天。任何帮助将不胜感激。

【问题讨论】:

  • 你能把你的模型包括进来吗?
  • 您好,请查找型号。 : 类 Userdetail(models.Model): appId = models.ForeignKey(AdmApplicationdata, models.PROTECT, db_column='appId', blank=True, null=True) Name = models.CharField(max_length=100, blank=True, null =True) totalPointsEarnedTillToday = models.IntegerField() createdDateTime = models.DateTimeField(blank=True, null=True)
  • 这是我写的查询:tp=models.UsrUserdetail.objects.filter(appId=4).values(TotalPoints=F("totalPoints"),name=F("firstName") ).annotate(year1=ExtractYear("createdDateTime"),month1=ExtractMonth("createdDateTime"),mp=Max("totalPoints")) 这是给year1和month1为无,不知道为什么,我已经包括ExtractYear和ExtractMonth图书馆
  • 非常感谢您的回复。这将返回一行,为我提供得分最高的用户的详细信息。但我的要求是获取每个月得分最高的用户的详细信息。

标签: django orm django-queryset annotate django-subquery


【解决方案1】:

虽然子查询中的GROUP BY 子句用ORM 表达有点困难,因为aggregate() 操作不会发出查询集,但使用Window 函数可以达到类似的效果:

UserDetail.objects.filter(total_points__in=UserDetail.objects.annotate(max_points=Window(
        expression=Max('total_points'),
        partition_by=[Trunc('created_datetime', 'month')]
    )).values('max_points')
)

一般来说,这种模式是用Subquery expressions 实现的。在这种情况下,我通过将查询集传递给 __in 谓词来隐式使用子查询。

using aggregates within subqueries 上的 Django 文档注释也与此类查询相关,因为您想在子查询中使用聚合的结果(我已经通过使用窗口函数避免了这种情况)。


但是,我认为您的查询可能无法正确捕获您想要执行的操作:如所写,它可能会返回给定月份中不是最好但与另一个最好的用户得分相同的用户的行在任何个月。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多