Запрос аннотирования для расчета суммы 2 табличных значений с помощью Django ORM - PullRequest
0 голосов
/ 22 октября 2018

У меня есть 2 таблицы

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.

Можно ли добиться этого с помощью одного запроса?

Нужна помощь, Заранее спасибо.

1 Ответ

0 голосов
/ 22 октября 2018

Вы можете написать это как:

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)
    )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...