Django ORM在批注多个聚合列时删除不需要的Group By [英] Django ORM remove unwanted Group by when annotate multiple aggregate columns

查看:23
本文介绍了Django ORM在批注多个聚合列时删除不需要的Group By的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Django ORM中创建类似以下内容的查询。

SELECT COUNT(CASE WHEN myCondition THEN 1 ELSE NULL end) as numyear
FROM myTable

以下是我编写的djang ORM查询

year_case = Case(When(added_on__year = today.year, then=1), output_field=IntegerField())

qs = (ProfaneContent.objects
                    .annotate(numyear=Count(year_case))
                    .values('numyear'))

这是由Django orm生成的查询。

SELECT COUNT(CASE WHEN "analyzer_profanecontent"."added_on" BETWEEN 2020-01-01 00:00:00+00:00 AND 2020-12-31 23:59:59.999999+00:00 THEN 1 ELSE NULL END) AS "numyear" FROM "analyzer_profanecontent" GROUP BY "analyzer_profanecontent"."id"

所有其他内容都很好,但Django在结尾处放置了group by,从而导致多行和错误的答案。我一点也不想这样。目前只有一列,但我将放置更多这样的列。

根据评论进行编辑 我将使用qs变量来获取当前年、月、周如何进行分类的值。

更新 根据我在这里得到的评论和回答,让我澄清一下。我只想在数据库端这样做(显然使用Django ORM,而不是原始SQL)。这是一个简单的SQL查询。在Python端执行任何操作都将是低效的,因为数据可能太大。这就是我希望数据库根据案例条件获得记录总和的原因。 我将在将来添加更多这样的列,因此像len()或.count这样的列将不起作用。

我只想使用Django ORM创建上述查询(不自动附加GROUP BY)。

推荐答案

在注释中使用聚合时,django需要有某种类型的分组,如果没有,则默认为主键。因此,您需要在.annotate()之前使用.values()Please see django docs

但要完全删除GROUP BY,您可以使用静态值,而Django足够聪明,可以完全删除它,因此您可以使用ORM查询获得结果,如下所示:

year_case = Case(When(added_on__year = today.year, then=1), output_field=IntegerField())

qs = (ProfaneContent.objects
                    .annotate(dummy_group_by = Value(1))
                    .values('dummy_group_by')
                    .annotate(numyear=Count(year_case))
                    .values('numyear'))

这篇关于Django ORM在批注多个聚合列时删除不需要的Group By的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆