我有两个名为User
和Transaction
的模型。在这里,我想获得状态为成功的所有用户的交易金额总和。
我尝试了子查询,但是我没有得到如何用条件注释子查询的集合
class User(models.Model):
name = models.CharField(max_length=128)
class Transaction(models.Model):
user = models.ForeignKey(User)
status = models.CharField(choices=(("success", "Success"),("failed", "Failed")))
amount = models.DecimalField(max_digits=10, decimal_places=2)
subquery = Transaction.objects.filter(status="success", user=OuterRef('pk')).aggregate(total_spent = Coalesce(Sum('amount'), 0))
query = User.objects.annotate(total_spent=Subquery(subquery:how to do here ?)).order_by(how to order here by total_spent)
答案 0 :(得分:0)
要使用子查询,请使用以下命令:
query=User.objects.annotate(total_spent=Subquery(subquery.values("user")[:1])).order_by("total_spent")
答案 1 :(得分:0)
您可以点击以下查询:
from django.db.models import Avg, Count, Min, Sum
User.objects.filter(status="success").annotate(total_amount=Sum('transaction__amount'))
答案 2 :(得分:0)
通过django-sql-utils软件包,这变得更加容易。
from django.db.models import Sum,
from sql_util.utils import SubqueryAggregate
User.objects.annotate(
total_spend=SubqueryAggregate('transaction__amount',
filter=Q(status='success'),
aggregate=Sum)
)
如果您想做长远的事情(没有django-sql-utils),则需要了解有关子查询的这两件事:
使用前无法评估
它只能返回具有单个列的单个记录
因此,您无法在子查询上调用aggregate
,因为这会立即评估子查询。相反,您必须注释该值。您还必须按外部ref值进行分组,否则,您将仅对每个Transaction进行注释。
subquery = Transaction.objects.filter(
status='success', user=OuterRef('pk')
).values(
'user__pk'
).annotate(
total_spend=Sum('amount')
).values(
'total_spend'
)
第一个.values
导致正确的分组依据。第二个.values
导致选择所需的一个值。
答案 3 :(得分:0)
当模型上有排序设置时,建议的解决方案对我不起作用。
subquery.query.clear_ordering(True)
我需要清除顺序以使其再次工作。
def with_installment_reservations_amounts(self):
"""
Sum of initial amount of active installment reservations annotated in _installment_reservations_initial_amount
Sum of principal amount of active installment reservations annotated in _installment_reservations_amount
`.values('customer')` in subquery is used to properly sum values. See https://stackoverflow.com/questions/55925437/django-subquery-with-aggregate for more details.
also this does not work when there is an ordering set on a model for some reason, so we need to clear it.
"""
reservation_query = InstallmentReservation.objects.filter(customer_id=OuterRef('pk')).active().values('customer')
reservation_query.query.clear_ordering(True)
return self.annotate(
_installment_reservations_amount=Coalesce(Subquery(reservation_query.annotate(sum=Sum('amount_principal')).values('sum')[:1]), Decimal(0),),
_installment_reservations_initial_amount=Coalesce(Subquery(reservation_query.annotate(sum=Sum('initial_installment_amount')).values('sum')[:1]), Decimal(0),),
)
整个代码示例 - 查询集上的一个方法 - 希望对您有所帮助
sum(request_total)