【问题标题】:Django Select from a SubqueryDjango 从子查询中选择
【发布时间】:2021-11-25 09:28:30
【问题描述】:

我想使用窗口函数进行查询,然后在子查询上通过聚合进行一些分组。但我无法使用 ORM 方法。它将返回aggregate function calls cannot contain window function calls

有什么方法可以在不使用.raw()的情况下进行如下SQL查询

SELECT a.col_id, AVG(a.max_count) FROM (
  SELECT col_id,
  MAX(count) OVER (PARTITION BY part_id ORDER BY part_id) AS max_count
  FROM table_one
) a
GROUP BY a.col_id;

例子

table_one

| id | col_id | part_id | count |
| -- | ------ | ------- | ----- |
| 1  | c1     | p1      | 3     |
| 2  | c2     | p1      | 2     |
| 3  | c3     | p2      | 1     |
| 4  | c2     | p2      | 4     |

首先我想根据 part_id 获得最大基数

| id | col_id | part_id | count | max_count |
| -- | ------ | ------- | ----- | --------- |
| 1  | c1     | p1      | 3     | 3         |
| 2  | c2     | p1      | 2     | 3         |
| 3  | c3     | p2      | 1     | 4         |
| 4  | c2     | p2      | 4     | 4         |

最后通过 col_id 得到 max_count 组的平均值

| col_id | avg(max_count) |
| ------ | -------------- |
| c1     | 3              |
| c2     | 3.5            |
| c3     | 4              |

我现在拥有的模型

def Part(models.Model):
    part_id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    name = models.CharFields()

def Col(models.Model):
    part_id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    name = models.CharFields()

def TableOne(models.Model):
    id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    col_id = models.ForeignKey(
        Col,
        on_delete=models.CASCADE,
        related_name='table_one_col'
    )
    part_id = models.ForeignKey(
        Part,
        on_delete=models.CASCADE,
        related_name='table_one_part'
    )
    count = models.IntegerField()

我想在分区之后进行分组。这是我做的查询会带来错误。

query = TableOne.objects.annotate(
    max_count=Window(
        expression=Max('count'),
        order_by=F('part_id').asc(),
        partition_by=F('part_id')
    )
).values(
    'col_id'
).annotate(
    avg=Avg('max_count')
)

【问题讨论】:

  • 如果你有 Django 模型和查询集尝试,你能提供吗?
  • 我已经附上了模型和我所做的查询
  • 不清楚你想达到什么目的,你能提供例子吗?您是否为子查询中table_one 中的每个part_id 获得max count?如何从中获得平均水平?
  • 对不起,我在模型上犯了一个错误,我已经更正并提供了示例

标签: python python-3.x django django-models django-rest-framework


【解决方案1】:

你可以在 Django 中使用subqueries,你不需要使用窗口函数。首先,子查询是一个Part 查询集,使用来自TableOne 的最大计数进行注释

from django.db.models import Avg, Max, Subquery, OuterRef

parts = Part.objects.filter(
    id=OuterRef('part_id')
).annotate(
    max=Max('table_one_part__count')
)

然后使用子查询中的最大计数注释 TableOne 查询集,在我们要分组的列上执行 values (col_id ),然后再次使用平均值注释以生成所需的输出

TableOne.objects.annotate(
    max_count=Subquery(parts.values('max')[:1])
).values(
    'col_id'
).annotate(
    Avg('max_count')
)

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 2019-04-04
    • 2012-02-13
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 2014-12-13
    相关资源
    最近更新 更多