python - 如何使用注释和聚合在 Django 的 ORM 中执行此 GROUP BY 查询

标签 python django orm group-by

我真的不知道如何将 GROUP BYHAVING 翻译成 Django 的 QuerySet.annotateQuerySet.aggregate 。我正在尝试将此 SQL 查询转换为 ORM 语言

SELECT EXTRACT(year FROM pub_date) as year, EXTRACT(month from pub_date) as month, COUNT(*) as article_count FROM articles_article GROUP BY year,month;

输出这个:

[(2008.0, 10.0, 1L), # year, month, number of articles
(2009.0, 2.0, 1L),
(2009.0, 7.0, 1L),
(2008.0, 5.0, 3L),
(2008.0, 9.0, 1L),
(2008.0, 7.0, 1L),
(2009.0, 5.0, 1L),
(2008.0, 8.0, 1L),
(2009.0, 12.0, 2L),
(2009.0, 3.0, 1L),
(2007.0, 12.0, 1L),
(2008.0, 6.0, 1L),
(2009.0, 4.0, 2L),
(2008.0, 3.0, 1L)]

我的 Django 模型:

class Article(models.Model):
    title = models.CharField(max_length=150, verbose_name=_("title"))
    # ... more 
    pub_date = models.DateTimeField(verbose_name=_('publishing date'))

这个项目应该在几个不同的数据库系统上运行,所以我尽量远离纯 SQL。

最佳答案

我认为要在一个查询中执行此操作,您可能必须将月份和年份作为单独的字段...

Article.objects.values('pub_date').annotate(article_count=Count('title'))

这将按 pub_date group by。但是我想不出有什么方法可以在那里内联执行与 extract 函数子句等效的操作。

如果您的模型是:

class Article(models.Model):
    title = models.CharField(max_length=150, verbose_name=_("title"))
    # ... more 
    pub_date = models.DateTimeField(verbose_name=_('publishing date'))
    pub_year = models.IntegerField()
    pub_month = models.IntegerField()

然后你可以这样做:

Article.objects.values('pub_year', 'pub_month').annotate(article_count=Count('title'))

如果您要这样做,我建议通过覆盖 save() 方法自动填充 pub_yearpub_month文章并从 pub_date 中提取值。


编辑:

一种方法是使用 extra ;但它不会授予您数据库独立性...

models.Issue.objects.extra(select={'year': "EXTRACT(year FROM pub_date)", 'month': "EXTRACT(month from pub_date)"}).values('year', 'month').annotate(Count('title'))

虽然这可行,但我认为(未经测试),如果您更改数据库服务器,它将要求您修改 extra 字段。例如,在 SQL Server 中,您将执行 year(pub_date) 而不是 extract(year from pub_date)...

如果您想出一个自定义模型管理器,并显着标记为需要此类依赖于数据库引擎的更改,这可能还不错。

关于python - 如何使用注释和聚合在 Django 的 ORM 中执行此 GROUP BY 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1908741/

相关文章:

java - 如何从计算行数的 SQL 查询开始正确实现 Hibernate SQL 查询?

java - hibernate :创建名称为小写的表

python - 为什么 joblib 并行执行会使运行时慢很多?

django - 如何在生产数据库的副本上运行 Django 测试?

python - 为什么 Python 中的元组使用 reversed 但没有 __reversed__?

python - Django "Did you mean?"查询

javascript - AngularJS 注销和重新登录

c# - NHibernate DuplicateMappingException 当两个类具有相同的名称但不同的命名空间时

python - Pygame-让子弹朝光标方向射击

python - 向请求 session 添加 cookie