【发布时间】:2020-12-03 01:27:14
【问题描述】:
我想在 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 变量来获取我在当前年、月、周中的分类方式的值。
更新 根据 cmets 和答案,我来到这里让我澄清一下。我只想在数据库端执行此操作(显然使用 Django ORM 而不是 RAW SQL)。它是一个简单的 sql 查询。在 Python 端做任何事情都会效率低下,因为数据可能太大。这就是为什么我希望数据库根据 CASE 条件获得记录总和的原因。 以后我会添加更多这样的列,所以像 len() 或 .count 这样的列将不起作用。
我只想使用 Django ORM 创建上述查询(没有自动附加的 GROUP BY)。
【问题讨论】:
-
我有点不清楚你打算如何使用这个 qs 变量
-
可能是我,但是....这不只是
ProfaneContent.objects.filter(added_on__year=today.year).count()的一种奇特的写作方式吗? -
是的,但正如我提到的,我还将添加其他列。所以计数不会在那里工作。这些也是解决方法。我只是想要一个 django ORM 查询。
-
是的,但是在这种情况下算作注释是无稽之谈。正如@hynekcer 所展示的那样,这只会返回一行。 Annotate 用于向每一行添加一些内容,而不是一组行。
-
也许混淆来自您对计数的命名和使用。你真的想用一个布尔值来注释每一行,表明它是当前年份吗?因为那么只需摆脱 Count 并正确命名它。
标签: sql django django-models orm django-orm