annotate查询,用于使用django orm计算2个表值的和

epggiuax  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(413)

我有两张table

Class Billing(models.Model):
 id=models.AutoField(primary_key=True)
 .....
 #Some more fields
 ....

Class BillInfo(models.Model):
  id=models.AutoField(primary_key=True)
  billing=models.ForeignKey(Billing)
  testId=models.ForeignKey(AllTests)
  costOfTest=models.IntegerField(default=0)
  concession=models.IntegerField(default=0)

在这里 BillInfo 是垂直表,即 Billing 有多个 BillInfo . 这里我要计算 Sum(costOfTest - concession) 一个单身汉 Billing .
我可以使用单个查询来实现这一点吗?
需要帮助,提前谢谢。

k2arahey

k2arahey1#

你可以这样写:

from django.db.models import F, Sum

Billing.objects.annotate(
    the_sum=Sum(F('billinfo__costOfTest') - F('billinfo__concession'))
)

这里每 Billing 此中的对象 QuerySet 将有一个额外属性 .the_sum 这是所有的总和 costOfTest s减去 concession 所有相关的 BillingInfo 物体。
计算此值的sql查询将大致如下所示:

SELECT billing.*
       SUM(billinginfo.costOfTest - billinginfo.concession) AS the_sum
FROM billing
LEFT OUTER JOIN billinginfo ON billinginfo.billing_id = billing.id
GROUP BY billing.id

因此,当您“具体化”查询时,查询将获得所有查询的总和 Billing 单个调用中的对象。
为了 Billing 没有任何关联的对象 BillingInfo ,的 the_sum 属性将为 None ,我们可以通过使用 Coalesce [django doc]功能:

from django.db.models import F, Sum, Value
from django.db.models.functions import Coalesce

Billing.objects.annotate(
    the_sum=Coalesce(
        Sum(F('billinfo__costOfTest') - F('billinfo__concession')),
        Value(0)
    )
)

相关问题