django - 带有聚合的 Django 子查询
问题描述
我有两个模型叫做User
and 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)
解决方案
使用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
原因是选择您想要的一个值。
推荐阅读
- c# - htmlagilityPack:网页不返回完整的 html
- typescript - 为什么我从这个函数中得到 NaN?
- c - 如何在c中增加结构矩阵中的值?
- javascript - 如何隐藏具有重复数据属性的孩子的所有父母
- r - 如何在R中使用gather()函数来堆叠分散到一列中的数据
- r - 更改绘图中一条线的颜色和线型
- c++ - 如何在 Qt 中放大/缩小图像的选定部分?
- visual-studio - 构建时如何阻止.net-core不断添加文件夹
- javascript - JSON 从 API 获取 Javascript,但我想从我自己的工作中获取
- visual-studio-code - 让 Jedi 查看代码完成的其他路径