【问题标题】:Annotate query for calculate sum of 2 table value with Django ORM使用 Django ORM 注释查询以计算 2 个表值的总和
【发布时间】:2019-03-26 14:23:58
【问题描述】:

我有两张桌子

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。在这里,我想计算单个BillingSum(costOfTest - concession)

我可以使用单个查询来实现吗?

需要帮助,提前致谢。

【问题讨论】:

  • BillInfoBillingForeignKey 是什么?
  • 是的,问题已更新。

标签: python mysql django django-models django-rest-framework


【解决方案1】:

你可以这样写:

from django.db.models import F, Sum

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

这里QuerySet 中的每个Billing 对象都将有一个额外的属性.the_sum,它是所有costOfTests 减去所有相关BillingInfoconcession 的总和对象。

计算此值的 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 对象的总和。

对于没有任何相关BillingInfoBilling对象,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)
    )
)

【讨论】:

  • BillingInfo 具有 Billing 作为 ForeignKey。收到错误django.core.exceptions.FieldError: Cannot resolve keyword 'billinfo' into field.
  • @GAJESHPANIGRAHI:确实,正如您在查询中看到的那样,我们在 JOIN 中使用了此外键的 billing_id 对应项。
  • @GAJESHPANIGRAHI:关键是如果你从模型AB 定义一个ForeignKey,Django 会构造一个从B 引用的隐式 关系到A
  • 但我想从Billing 模型访问BillInfo,而BillingBillInfo 的ForeignKey。有一个对象billinginfo_set
  • @GAJESHPANIGRAHI:我们正在Billing 访问BillingInfo。注意F('billinginfo__...')ForeignKey 位于其他位置的事实 很重要,因为数据库会生成JOIN,并且通常会有适当的索引来正确执行此操作。并不是因为数据库中没有explicitForeignKey,所以获取relatedBillingInfo的集合是个问题。
猜你喜欢
  • 2018-06-21
  • 2019-10-13
  • 2018-08-26
  • 2020-01-26
  • 2019-02-24
  • 2016-10-06
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多