记录 django 外键关联统计
chenzuoqing Lv3

记录 django 外键关联统计

记录几个统计问题实例

  1. 从主机表统计每个主机的装服数量,ServerModelhost 字段关联 HostModel,在 1.11 中实测可用。统计后的对象将额外生成一个 __count 后缀的字段,并且可以用于排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
HostModel.objects.using(gameName).values('id').annotate(Count('servermodel')).order_by('servermodel__count')

添加过滤
>>> from django.db.models import Count, When, Case
>>> person = Person.objects.annotate(Count(Case(When(task_set__is_done=True, then=0))).first()
>>> person.task_set__count

# 2.0往后
>>> from django.db.models import Count, Q
>>> person = Person.objects.annotate(
... Count('task_set', filter=Q(task_set__is_done=True))
... ).first()
>>> person.task_set__count
10
  1. sum(x) .. group by field
    如下PerformanceStatsModel 有字段[host_id(外键),mem1,mem2,mem3,created_date],想得到某机器在多天时各 mem 字段统计的总和数据。
    这里的特点是 annotate 注解(分组)会按 order_by 字段,若想按host_id分组,model中默认可能会是 "-id" 排序。我们这里的结果必须用 .values("host").order_by("host") 才能实现像 SQL 中的 group by host_id,最后 annotate 中的参数与 select sum(mem1) as mem_1, sum(mem2) as mem_2, sum(mem3) as mem_3 from ... 相同
1
2
3
4
5
6
7
8
9
10
11
PerformanceStatsModel.objects.using(gameName).filter(
host__in=hosts, mem3=0, created_date__gte=d).values("host").order_by("host").annotate(
mem_1=Sum("mem1"), mem_2=Sum("mem2"), mem_3=Sum("mem3")
)

# 结果集是一个个统计好的字典:
{'host': 175, 'mem_1': 2880, 'mem_2': 0, 'mem_3': 0}
{'host': 178, 'mem_1': 2880, 'mem_2': 0, 'mem_3': 0}

# 结果集中的字典是可以用filter过滤的,相当于SQL中group by后面的: having maxMem = 0
PerformanceStatsModel.objects.using(gameName).filter(host__in=hosts, created_date__gte=d).values("host").order_by("host").annotate(maxMem=Sum("mem3")).filter(maxMem=0)
 Comments