如何用Django ORM实现用户-账户-交易的分组聚合查询?
模型伪代码定义
class User: name: string class Account: owner: foreignkey(User, related_name="accounts") class Transactions: type: Enum(1,2,3) account: foreignkey(Account, related_name="transactions") value: Int
问题
如何使用Django ORM编写对应以下SQL的查询语句?
SELECT user.id, type, AVG(value) as type_average FROM user JOIN account ON account.owner = user.id JOIN transactions ON transactions.account = account.id GROUP BY user.id, type
Django ORM 查询实现
可以通过跨模型关联查询,结合annotate和values方法实现,以下是两种可行写法:
写法一:从User模型出发查询
from django.db.models import Avg result = User.objects.values('id', 'accounts__transactions__type').annotate( type_average=Avg('accounts__transactions__value') ).order_by('id', 'accounts__transactions__type')
写法二:从Transactions模型出发查询(字段名更直观)
from django.db.models import Avg result = Transactions.objects.values( 'account__owner__id', 'type' ).annotate( type_average=Avg('value') ).order_by('account__owner__id', 'type')
关键说明
values()方法指定需要返回和分组的字段,对应SQL中的SELECT和GROUP BY部分annotate()方法用于计算聚合函数,这里的Avg('value')对应SQL中的AVG(value) as type_average- Django ORM通过双下划线
__表示跨模型的外键关联,比如account__owner__id对应SQL中关联到user表的id字段
内容的提问来源于stack exchange,提问作者Don Bhrayan Singh
相关产品推荐
相关产品推荐

