【问题标题】:Can I filter on multiple contrains with django aggregate functionlity?我可以使用 django 聚合功能过滤多个约束吗?
【发布时间】:2009-07-12 14:51:03
【问题描述】:

如何使用 django 的聚合功能计算具有多个约束的记录?

使用 django 主干我试图用 django 聚合替换复杂的数据库特定 SQL 语句。例如,假设我有一个数据库,其中包含在许多域(想想 .co.uk、.com、.etc)上运行的博客的表,每个都需要许多 cmets:

domains <- blog -> comment

以下 SQL 对每个域的 cmets 进行计数:

SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D
LEFT OUTER JOIN blog AS B ON D.blog_id = B.id
LEFT OUTER JOIN comment AS C ON B.id = C.blog_id
GROUP BY D.id

这很容易复制:

Domain.objects.annotate(Count('blogs__comments'))

更进一步,我希望能够添加一个或多个约束并复制以下 SQL:

SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D
LEFT OUTER JOIN blog AS B ON D.blog_id = B.id
LEFT OUTER JOIN comment AS C ON B.id = C.blog_id
    AND C.active = True
GROUP BY D.id

这很难复制,因为 django 似乎包括使用 WHERE 子句过滤整个 shaboodle:

Domain.objects.filter(blogs__comments__active=True)
              .annotate(Count('blogs__comments'))

SQL 是这样的:

SELECT ..., COUNT(comment.id) AS blog__comments__count FROM domain
LEFT OUTER JOIN blog ON domain.blog_id = blog.id
LEFT OUTER JOIN comment ON blog.id = comment.blog_id
WHERE comment.active = True
GROUP BY domain.id
ORDER BY NULL

如何说服 django 对适当的 LEFT OUTER JOIN 施加额外限制?这很重要,因为我想计算那些没有 cmets 的博客。

【问题讨论】:

标签: django aggregate


【解决方案1】:

我不知道如何使用 Django 查询语言执行此操作,但您始终可以运行原始 SQL 查询。如果你还不知道怎么做,这里有一个例子:

from django.db import connection

def some_method(request, some_parameter):
    cursor = connection.cursor()
    cursor.execute('SELECT * FROM table WHERE somevar=%s', [some_parameter])
    rows = cursor.fetchall()

更多细节可以在 Django 在线书籍中找到:http://www.djangobook.com/en/2.0/chapter05/

查找“在视图中进行数据库查询的“愚蠢”方式”部分。如果您不想使用“愚蠢”的方式,我不确定您的选择是什么。

【讨论】:

  • 我最初是使用 SQL 查询来做的,但是当我从 MySQL 转移到 PostgreSQL 时,它变成了梨形。我现在已经修复了它,但仍然可以避免 ral SQL 查询。
猜你喜欢
  • 2018-06-16
  • 1970-01-01
  • 2015-12-10
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
相关资源
最近更新 更多