Django查询:获取外键关联字段求和Top10客户
获取关联Group字段总和最高的前10位Client
我来帮你搞定这个需求!要实现按关联Group的sc_done、sc_analyze、sc_error三者总和排序,取前10位Client,我们可以用Django的聚合查询和字段引用功能来完成,具体方案如下:
完整查询代码
首先需要导入Django ORM的相关工具函数:
from django.db.models import Sum, F, Coalesce
然后编写查询语句:
# 计算每个Client的总sc值,并取前10位 top_clients = Client.objects.annotate( sc_count=Sum( Coalesce(F('group__sc_done'), 0) + Coalesce(F('group__sc_analyze'), 0) + Coalesce(F('group__sc_error'), 0) ) ).order_by('-sc_count')[:10]
代码解释
annotate():为每个Client实例添加一个临时字段sc_count,用来存储该Client所有关联Group的三个sc字段总和。Coalesce():处理字段为null的情况(你的模型允许这三个字段为null),把null转换成0,避免求和时出现null值导致排序异常。F('group__sc_done'):使用双下划线__跨关联模型引用字段,这里表示当前Client关联的所有Group的sc_done字段。Sum():对所有关联Group的三个字段之和进行求和,得到该Client的总sc值。order_by('-sc_count')[:10]:按sc_count降序排列,取前10条结果。
转换为目标格式结果
如果需要把结果转换成类似{'client': 'client-1', 'sc_count': X}的字典格式,可以这样做:
result_list = [ {'client': client.name, 'sc_count': client.sc_count} for client in top_clients ]
或者直接用values()方法批量获取:
result_list = top_clients.values('name', 'sc_count') # 如果你想重命名键名,可以用annotate的时候指定,或者后续处理
可选:过滤无关联Group的Client
如果某个Client没有关联任何Group,它的sc_count会是0。如果不想包含这类Client,可以在查询前添加过滤条件:
top_clients = Client.objects.filter(group__isnull=False).annotate( sc_count=Sum( Coalesce(F('group__sc_done'), 0) + Coalesce(F('group__sc_analyze'), 0) + Coalesce(F('group__sc_error'), 0) ) ).order_by('-sc_count')[:10]
这样就能得到你需要的前10位高总和的Client啦!
内容的提问来源于stack exchange,提问作者pe.kne
相关产品推荐
相关产品推荐

