【问题标题】:django : using if else or while else inside Sum function with annotation? Cannot compute Sum('<CombinedExpression:..') is an aggregatedjango:在带有注释的 Sum 函数中使用 if else 或 while else?无法计算 Sum('<CombinedExpression:..') 是一个聚合
【发布时间】:2020-06-27 06:59:06
【问题描述】:

我想在 annotate 中为我的 Sum 函数设置一个条件,我尝试使用 Case When 但它在我的情况下不起作用

这是我的models.py

class MyModel(models.Model):
    name = models.ForeignKey(Product, on_delete=models.CASCADE)
    order = models.IntegerField()
    price = models.IntegerField()

class Prodcut(models.Model):
    name = models.CharField(max_lenth=20)
    cost = models.IntegerField()
    price = models.IntegerField()

我想要这样的东西

total = F('price')*F('order')
base = (F(name__cost')+F('name__price')) * F('order')
if  total> base:
    income = Sum(F('total') - F('base'))

我试过了

MyModel.objects.values('name__name').annotate(total=(Sum(F('price') * F('order'),output_field=IntegerField())),
                        base=(Sum((F('name__price')+F('name__cost'))*F('order'),output_field=IntegerField())
                            ),
                        income=Sum(
                            Case(When(total__gt=F('base') , then=Sum(F('total') - F('base'))),default=0),output_field=IntegerField()),)

但这会引发此错误:

无法计算 Sum(''): '' 是一个聚合

我不想使用 .filter(income__gt=0),因为它会阻止 quantity 计数 我不想把income算在那些失去销售的产品上 例如

我在MyModel(name=mouse ,order=2,price=20) 上发帖,在我的产品模型中,我有鼠标产品Product(name=mouse,cost=4,price=10) 的这些信息,当我计算找到该产品的收入时:(2 *20) - ((4+10)*2) =&gt; 40 - 28 = 12,但有时结果会是负数(2*10) - ((4+10)*2) =&gt; 20 - 28 = -8时的价格

*我使用 mysql v:8 作为数据库

我想防止负数添加到我的income 相对于其他列quantity

【问题讨论】:

    标签: python mysql django


    【解决方案1】:

    问题是您不能在同一查询的另一个聚合中使用聚合(总计和基数)。只有一个 GROUP BY 子句,Django 无法在此处自动生成有效查询。据我了解,你需要先计算total和base,找到每个MyModel的收入,然后才能产生一个聚合:

    MyModel.objects.annotate(
        total=F('price') * F('order'),
        base=(F('name__price') + F('name__cost')) * F('order'),
        income=Case(
            When(total__gt=F('base'), then=F('total') - F('base')),
            default=0,
            output_field=IntegerField()
        )
    ).values('name__name').annotate(income=Sum('income'))
    

    附:请格式化您的代码,以便人们可以毫无困难地阅读它:)

    P.P.S 我可能会看到另一种方式,你不需要 Sum() 来计算收入,因为总和基数已经是总和

    MyModel.objects.values('name__name').annotate(
        total=Sum(F('price') * F('order')),
        base=Sum((F('name__price') + F('name__cost')) * F('order')),
    ).annotate(
        income=Case(
            When(total__gt=F('base'), then=F('total') - F('base')),
            default=0,
            output_field=IntegerField()
        )
    )
    

    【讨论】:

    • 我感激不尽,你拯救了我的一天
    【解决方案2】:

    试试这个,也许需要一些曲折,想法是使用Conditional Expressions

    from django.db.models import Case, When, Value, IntegerField
    
    MyModel.objects.values('name__name').annotate(
           total = F('price')*F('order')
           base = (F('name__cost') + F('name__price')) * F('order')
        ).annotate(
           income = Case(
              When(total__gt=F('base'), then=Sum(F('total')-F('base'))
        ), default = F('total'), output_field=IntegerField())
    )
    

    【讨论】:

    • 谢谢,我也试过了,但它引发了这个错误(无法计算 Sum(''): '' 是一个聚合
    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 2016-11-16
    • 2019-03-20
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多