首页 > 解决方案 > Django 查询以获取每个月表现最好的人

问题描述

我需要获取每个月表现最好的人,这是下面的 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 天。任何帮助将不胜感激。

标签: djangoormdjango-querysetannotatedjango-subquery

解决方案


虽然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表达式实现的。在这种情况下,我通过将查询集传递给__in谓词来隐式使用子查询。

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


但是,我相信您的查询可能无法正确捕获您想要做的事情:正如所写的那样,它可以为在给定月份中不是最好但与在任何月份中最好的另一个用户具有相同分数的用户返回行.


推荐阅读