Django 2.2.3中如何通过单查询正确计算多条件统计值?
解决Djongo中Django 2.2.3聚合多条件统计的问题
问题原因
你遇到的问题是因为Djongo(MongoDB的Django适配后端)在Django 2.2版本中,对Count聚合函数的filter参数支持不完善,导致过滤条件没有被正确解析执行,所有带filter的Count都返回了总记录数。
替代解决方案
改用Sum结合Case/When的组合来模拟你需要的SQLCOUNT(CASE...)逻辑,这种写法能被Djongo正确转换为MongoDB的聚合管道,得到预期结果:
from django.db.models import Count, Case, When, IntegerField, Sum result = MyModel.objects.aggregate( # 统计所有user_id非空的记录(如果要统计总记录数,改用Count('__all__')) total=Count('user_id'), # 统计group_id=1的记录数 group_1_value=Sum( Case( When(group_id=1, then=1), default=0, output_field=IntegerField() ) ), # 统计group_id=2的记录数 group_2_value=Sum( Case( When(group_id=2, then=1), default=0, output_field=IntegerField() ) ), # 统计user_id匹配指定值的记录数 test=Sum( Case( When(user_id='just_a_fake_id', then=1), default=0, output_field=IntegerField() ) ) )
额外说明
- 你原来的
total=Count('user_id')返回0,大概率是因为所有记录的user_id字段都是null,Count('字段名')会自动排除该字段为null的记录。如果需要统计所有记录总数(不管user_id是否为空),请将total改为Count('__all__')或者Count('pk')。 - 这种
Sum+Case的写法和你目标SQL的逻辑完全一致:当条件满足时返回1,否则返回0,求和的结果就是符合条件的记录数,等价于COUNT(CASE...)。
内容的提问来源于stack exchange,提问作者shayms8
相关产品推荐
相关产品推荐

