我有两个模型称为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)
Run Code Online (Sandbox Code Playgroud)
小智 27
使用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)
)
Run Code Online (Sandbox Code Playgroud)
如果你想做得很长(没有 django-sql-utils),你需要知道关于子查询的这两件事:
在使用之前无法对其进行评估
它只能返回单列的单条记录
因此,您不能调用aggregate子查询,因为这会立即评估子查询。相反,您必须注释该值。您还必须按外部 ref 值分组,否则您只需独立注释每个事务。
subquery = Transaction.objects.filter(
status='success', user=OuterRef('pk')
).values(
'user__pk'
).annotate(
total_spend=Sum('amount')
).values(
'total_spend'
)
Run Code Online (Sandbox Code Playgroud)
第一个.values导致正确的分组依据。第二个.values原因是选择您想要的一个值。
Sla*_*ava 12
你可以这样做:
subquery = Transaction.objects.filter(
status="success", user=OuterRef('pk')
).annotate(
total_spent = Coalesce(Func('amount', function='Sum'), Decimal(0))
).values('total_spent')
query = User.objects.annotate(
total_spent=Subquery(subquery)
).order_by('total_spent')
Run Code Online (Sandbox Code Playgroud)
有关此方法的更多详细信息,您可以在此答案中看到:/sf/answers/4831451271/
小智 -2
要使用子查询,请使用:
query=User.objects.annotate(total_spent=Subquery(subquery.values("user")[:1])).order_by("total_spent")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6692 次 |
| 最近记录: |