sql - 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 而不是 RAW SQL)。它是一个简单的 sql 查询。在 Python 端做任何事情都会效率低下,因为数据可能太大。这就是为什么我希望数据库根据 CASE 条件获得记录总和的原因。我将来会添加更多这样的列,所以像 len() 或 .count 这样的东西将不起作用。
我只想使用 Django ORM 创建上述查询(没有自动附加的 GROUP BY)。
解决方案
在注释中使用聚合时,django 需要进行某种分组,如果没有,则默认为主键。所以,你需要使用.values()
before .annotate()
。请参阅 django 文档。
但是要完全删除组,您可以使用静态值,并且 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'))
推荐阅读
- vue.js - Sort Vue data table by selection
- python - 为什么我收到错误消息:无法获取数据库的路由表
- android - 如何在flutter的firestore中使用uid更新用户数据
- arrays - sscanf 重复字符后的值
- awk - 针对大数据优化 Bash 脚本
- xamarin.forms - 如何以 xamarin 形式检测设备的大小
- c# - Kestrel Port:0,如何检测自动选择的端口
- fpga - 将简单反转(非函数)应用于 OBUFDS
- angular - 错误:将 Angular 8 转换为 Angular Universal 时“无法读取未定义的属性‘种类’”
- python - python脚本中的正则表达式