在学习Django聚合与分组查询中,发现value与annotate的顺序不同时,查询结果大相径庭,经过一下午的研究,终于弄明白了,现在分享给大家,先上结论:
结论
- value在annotate前面时,相当于
group by
,即models.表名.objects.values('group by 字段').annotate(统计字段) - value放在annotate后面时,相当于
select
- annotate前面没有value时,默认按当前表的主键分组
验证
表格准备
查询
value放在前面时
ret=models.Student.objects.values('gender').annotate(count=Count('sid')).order_by('-count')
print(ret)
等价于以下sql语句
SELECT `app_student`.`gender`, COUNT(`app_student`.`sid`) AS `count` FROM `app_student` GROUP BY `app_student`.`gender` ORDER BY `count` DESC
执行结果
<QuerySet [{'gender': '女', 'count': 6}, {'gender': '男', 'count': 5}]>
可以看到结果是按性别分组的
### value放在后面时
ret = models.Student.objects.annotate(count=Count('sid')).values('gender').order_by('-count')
print(ret)
等价于以下sql语句
SELECT `app_student`.`gender` FROM `app_student` GROUP BY `app_student`.`sid` ORDER BY COUNT(`app_student`.`sid`) DESC
执行结果
<QuerySet [{'gender': '女'}, {'gender': '男'}, {'gender': '女'}, {'gender': '女'}, {'gender': '男'}, {'gender': '女'}, {'gender': '男'}, {'gender': '男'}, {'gender': '女'}, {'gender': '女'}, {'gender': '男'}]>
可以看到结果并没有按性别分组,而是每个学生作为一组,说明上述结论是正确的