在 Django 中对汇总值求和

问题描述 投票:0回答:1

我正在尝试在 Django 中实现以下 SQL 查询:

(该表包含每个地点每天的购买量。我想获得每个地点的最大数量,然后按州对它们进行分组,看看每个州最多可以出售多少)

select state, type, sum(amount)
    from (
        select l.state, dd.type, max(amount) as amount 
        from daily_data dd
        join locations l on l.id = dd.location_id
        where dd.type in ('purchases', 'returns')
        group by dd.location_id, dd.type
    )
    group by state, type

我从哪里得到这个:

NY,purchases,80
NY, returns,6
Maine,purchases,125
Maine, returns,12

但我对如何在 django 中实现这一目标感到困惑。

我试过这个:

daily_data.objects.filter(type__in=['purchases', 'returns']
        ).values('location', 'type'
        ).annotate(total=Max('amount')
        ).values('location__state','type'
        ).annotate(sum=Sum('total'))

但是我收到错误

django.core.exceptions.FieldError: Cannot compute Sum('total'): 'total' is an aggregate

我什至尝试了子查询,但这会生成一个错误的 SQL 查询,导致查询永远持续下去。

subquery = daily_data.objects.filter(
    location=OuterRef('location'),
    type=OuterRef('type')
).values('location', 'type').annotate(
    max_amount=Max('amount')
).values('max_amount')

annotated_data = daily_data.objects.filter(
    type__in=['purchases', 'returns']
).annotate(
    max_amount=Subquery(subquery)
).values(
    'location__state', 'type'
).annotate(
    total_max_amount=Sum('max_amount')
).order_by('location__state', 'type')

这会生成:

SELECT "state", "type", SUM((
        SELECT MAX(U0."amount") AS "total" FROM "daily_data" U0
        INNER JOIN "locations" U1 ON (U0."location_id" = U1."id")
        WHERE (U1."state" = ("state") AND U2."type" = "type") GROUP BY U0."location_id", U2."type")) AS "total"
FROM "daily_data"
    INNER JOIN "locations" ON ("location_id" = "locations"."id") WHERE where "type" in ('purchases', 'returns')
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             GROUP BY "state", "type"

这是多余且昂贵的......而且我还没有看到结果,因为它永远加载......

django group-by django-orm
1个回答
0
投票

您好,我不是 django orm 方面的专家,但对我来说,当使用 django 或 spring(java 框架)以编程方式创建查询变得复杂时,我通常更喜欢直接编写我的 sql,而 django 为您提供了这一点

django 原始 sql

你可以的地方

     result=daily_data.objects.raw(
        """
            select state, type, sum(amount)
            from (
                select l.state, dd.type, max(amount) as amount 
                from daily_data dd
                join locations l on l.id = dd.location_id
                where dd.type in ('purchases', 'returns')
                group by dd.location_id, dd.type
            )
            group by state, type
        """
    )

    for value in result.iterator():
        print(value)

并使用迭代器查看值,尽管这只是一个建议,希望它可能有所帮助:)

注意:使用raw方法时请务必遵循文档,防止sql注入。

© www.soinside.com 2019 - 2024. All rights reserved.