如何在 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" 

但是上面的结果不包含IDpublished_on 如果我将它们添加到它所分组的值中,这不是我想要的。我只想按nameauthor 分组,但想要其他字段或至少获得一个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 获得额外的列?的主要内容,如果未能解决你的问题,请参考以下文章

数据库中通过group by找出表中的重复数据

如何在 django 中将两列与 group by 相乘和求和

如何在WebElement中通过xpath查找子元素

如何在 django orm 中使用 Annotation 进行嵌套 Group By?

如何在 Django ORM 中执行 GROUP BY ... COUNT 或 SUM?

如何选择 COUNT(*) GROUP BY DJANGO? [复制]