如何在 Django 中通过 group by 获得额外的列?
Posted
技术标签:
【中文标题】如何在 Django 中通过 group by 获得额外的列?【英文标题】:How to get extra columns in group by in Django? 【发布时间】:2020-08-23 17:40:09 【问题描述】:我只想在带有值的注释结果中包含ID
(和其他字段)(即分组依据)。
我会用一个例子来解释(以下只是一个例子,请不要相信这个坏模型),
class Book(models.Model):
name = models.CharField()
version = models.IntegerField() # Assming its just a number that increments when each version is published like 1...2...3 and so on.
published_on = models.DateTimeField()
author = models.ForeignKey(User)
class Text(models.Model):
book_text = models.ForeignKey(Book)
我想要的是一本书的最大版本(或多个版本),我通过
Book.objects.values('name', 'author').annotate(Max('version'))
**Generated SQL (mysql) query**:
SELECT "name",
"author",
Max("version") AS "version__max"
FROM "book"
GROUP BY "name",
"author"
但是上面的结果不包含ID
或published_on
如果我将它们添加到它所分组的值中,这不是我想要的。我只想按name
和author
分组,但想要其他字段或至少获得一个ID。
Expected SQL:
SELECT "id",
"published_on",
"name",
"author",
Max("version") AS "version__max"
FROM "book"
GROUP BY "name",
"author"
【问题讨论】:
【参考方案1】:在 SQL 中,您不能选择不在 group by 语句中的字段。您应该通过附加查询获取 id,例如:
Book.object.filter(name=name_from_first_query, author=author_from_first_query, version=version_from_first_query
当然,您必须通过查询遍历您的组的结果。
【讨论】:
是的,你是对的,我想我必须使用 python 或 Subquery... 一个很好的解释我发现为什么建议在 select 和 group by 中使用相同的字段是here link ...但非常感谢。【参考方案2】:from django.db.models import F
Book.objects.values('name', 'author').annotate(Max('version'), id=F('id'))
在 django 中进行分组时。顺序很重要。我们传递需要通过查询集分组的值,并在注释函数中使用 F 表达式添加结果查询集中所需的额外元素。如果我们在值中添加id
,那么在进行分组时会考虑到它。
希望这可以清除:)
【讨论】:
虽然这段代码可能会解决问题,但一个好的答案还应该解释代码的什么以及它如何提供帮助。 所以这个方案看起来不错,发帖前我也试过了。但不知何故它不起作用......ID
被添加到 GROUP BY 查询中,并且像 Book.objects.values('name', 'author','id').annotate(Max('version'))
虽然此代码可能提供问题的解决方案,但强烈建议您提供有关此代码为何和/或如何回答问题的附加上下文。从长远来看,只有代码的答案通常会变得毫无用处,因为未来遇到类似问题的观众无法理解解决方案背后的原因。
添加解释以便更好地理解 :) 点赞【参考方案3】:
Book.objects.values('name', 'author').annotate(Max('version'), Max('id'))
【讨论】:
这个解决方案有效,但看起来很老套,但无论如何......谢谢。 虽然此代码可能提供问题的解决方案,但强烈建议您提供有关此代码为何和/或如何回答问题的附加上下文。从长远来看,只有代码的答案通常会变得毫无用处,因为未来遇到类似问题的观众无法理解解决方案背后的原因。以上是关于如何在 Django 中通过 group by 获得额外的列?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django 中将两列与 group by 相乘和求和
如何在 django orm 中使用 Annotation 进行嵌套 Group By?