django ORM 问题 - 注释和聚合 return 不一致的值
django ORM problem - Annotate and aggregate return inconsistent values
我发现 aggregate()
和 annotate()
不 return 相同的值...我真的很困惑。
我有以下型号:
class Invoice(models.Model):
pass
class InvoiceItem(models.Model):
invoice = models.ForeignKey(Invoice, related_name="items")
amount = models.PositiveIntegerField(null=False, blank=False, default=1)
price = models.DecimalField(max_digits=10, decimal_places=2, null=False, blank=False, default=0)
begin = models.DateField(null=True, blank=True)
当我想获得某个时间跨度内的总收入时,我有以下查询:
revenue = Invoice.objects.annotate(
first_date=Min('items__begin')).filter(
first_date__range=[start_date, end_date]).aggregate(
revenue=Sum(F('items__amount') * F('items__price'),
output_field=FloatField()))['revenue']
我尝试对 annotate()
做同样的事情,只是为了验证结果:
revenue_list = Invoice.objects.annotate(
first_date=Min('items__begin')).filter(
first_date__range=[start_date, end_date]).annotate(
revenue=Sum(F('items__amount') * F('items__price'),
output_field=FloatField()))
当我现在遍历元素并手动求和时 revenue
我得到的值与 revenue
不同。
有什么想法吗?不幸的是,在聚合之后,您无法再检查原始查询...
谢谢!
PS:我用 SQL 手动检查了这些值。 annotate
是对的...
好的,我找到了解决办法。 distinct()
或 values()
不起作用,但将乘法移动到第二个 annotate
:
revenue = Invoice.objects.annotate(
first_date=Min('items__begin')).filter(
first_date__range=[start_date, end_date]).annotate(
revenue_invoice=Sum(F('items__amount') * F('items__price'),
output_field=FloatField())).aggregate(
revenue=Sum('revenue_invoice', output_field=FloatField()))['revenue']
也许这对其他人有帮助...
我发现 aggregate()
和 annotate()
不 return 相同的值...我真的很困惑。
我有以下型号:
class Invoice(models.Model):
pass
class InvoiceItem(models.Model):
invoice = models.ForeignKey(Invoice, related_name="items")
amount = models.PositiveIntegerField(null=False, blank=False, default=1)
price = models.DecimalField(max_digits=10, decimal_places=2, null=False, blank=False, default=0)
begin = models.DateField(null=True, blank=True)
当我想获得某个时间跨度内的总收入时,我有以下查询:
revenue = Invoice.objects.annotate(
first_date=Min('items__begin')).filter(
first_date__range=[start_date, end_date]).aggregate(
revenue=Sum(F('items__amount') * F('items__price'),
output_field=FloatField()))['revenue']
我尝试对 annotate()
做同样的事情,只是为了验证结果:
revenue_list = Invoice.objects.annotate(
first_date=Min('items__begin')).filter(
first_date__range=[start_date, end_date]).annotate(
revenue=Sum(F('items__amount') * F('items__price'),
output_field=FloatField()))
当我现在遍历元素并手动求和时 revenue
我得到的值与 revenue
不同。
有什么想法吗?不幸的是,在聚合之后,您无法再检查原始查询...
谢谢!
PS:我用 SQL 手动检查了这些值。 annotate
是对的...
好的,我找到了解决办法。 distinct()
或 values()
不起作用,但将乘法移动到第二个 annotate
:
revenue = Invoice.objects.annotate(
first_date=Min('items__begin')).filter(
first_date__range=[start_date, end_date]).annotate(
revenue_invoice=Sum(F('items__amount') * F('items__price'),
output_field=FloatField())).aggregate(
revenue=Sum('revenue_invoice', output_field=FloatField()))['revenue']
也许这对其他人有帮助...