【问题标题】:Calculate the difference of 2 aggregated Sum in one query在一个查询中计算 2 个聚合 Sum 的差值
【发布时间】:2016-11-23 14:44:45
【问题描述】:

我有一个模型如下:

class Loan(models.Model):
    lender = models.ForeignKey(User, related_name='lender')
    borrower = models.ForeignKey(User, related_name='borrower')
    money = models.IntegerField()

我想做的是为用户计算总总额:

gross_total = Loans.object.filter(lender=user).annonate(Sum('money')) 
                - Loans.object.filter(borrower=user).annonate(Sum('money'))

我当前的总计算使用两个查询。我想要一个查询。

谢谢。

【问题讨论】:

    标签: django


    【解决方案1】:

    这可以通过conditional expressions来完成

    from django.db.models import Case, Value, When, IntegerField
    
    gross_total = Loans.object.aggregate(
        gross=Sum(
            Case(
                When(lender=user, then=F('money')),
                default=0, output_field=IntegerField)
            )
        ) - Sum(
            Case(
                When(borrower=user, then=F('money')),
                default=0, output_field=IntegerField)
            )
        )
    )
    

    【讨论】:

    • 这正是我需要的,甚至不知道我们可以在 django 中做到这一点。谢谢!! :)
    • 我需要像output_field=IntegerField()一样打电话给IntegerField
    【解决方案2】:

    首先,当您使用来自同一用户模型的两个外键时,您需要给它们一个“related_name”,如下所示:

    class Loan(models.Model):
        lender = models.ForeignKey(User, related_name='lender')
        borrower = models.ForeignKey(User, related_name='borrower')
        money = models.IntegerField()
    

    现在来回答你的问题,你需要的是这篇文章中给出的东西 -> How to group by AND aggregate with Django

    因此,您的问题所需的查询很可能是:

    gross_total = Loans.objects.filter(lender=user).values('user').annotate(score = Sum('money')) - Loans.objects.filter(borrower=user).values('user').annotate(score = Sum('money'))
    

    【讨论】:

    • 这不是我们想要的,我编辑了这个问题。顺便说一句,感谢 value('user') 不知道的事情
    • 没问题。如果你想要一个查询,那么我想你需要一个 F() 表达式。看到这个 -> docs.djangoproject.com/en/1.9/ref/models/expressions 我正在尝试为您更新的问题提供所需的答案。如果我愿意,那么我会添加另一个答案。
    猜你喜欢
    • 2010-09-21
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    相关资源
    最近更新 更多