Py006-01-19聚合查询和分组查询

聚合

  • aggregate聚合:返回值是字典,不再是queryset
  • 导入模块from django.db.models import Avg,Max,Min,Count
1
2
3
4
5
6
7
8
查询:所有书籍平均价格
res = Book.objects.all().argregate(Avg('price')) # {"price_avg":111.00} 这个key是默认生成的,你也可以自己指定

res = Book.objects.all().argregate(avg_price=Avg('price')) # {"avg_price":111.00}


# 查avg max min
res = Book.objects.all().argregate(Avg('price'),Max('price'),Min('price'))

分组查询

单表分组查询

  • annotate(聚合函数)
1
2
3
4
5
6
7
8
9
emp表

id name age salary dep
1 alex 12 2000 销售部
2 egin 22 3000 人事部
3 wen 22 5000 人事部

查询每个部门对应员工人数
sql:select count(id) from emp group by dep;

如何用orm查询分组数据

1
2
3
4
5
6
7
# orm模型 (单表)
class Emp(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
salary = models.DecimalField(max_digits=8,decimal_places=2)
dep = models.CharField(max_length=32)
province = models.CharField(max_length=32) # 省份
1
2
3
4
# 先录入一些数据
e1 = Emp.objects.create(name='alex',age=22,salary=2000,dep='教学部',province='山东省')
e2 = Emp.objects.create(name='egin', age=33, salary=5000, dep='保安部', province='山东省')
e3 = Emp.objects.create(name='yuan', age=21, salary=100000, dep='教学部', province='河北省')

示例1

1
2
3
4
5
6
7
8
# 查询每一个部门平均薪水
# select dep,avg(salary) from emp group by dep;
res = Emp.objects.values('dep').annotate(Avg('salary'))
print(res)

'''
<QuerySet [{'dep': '保安部', 'salary__avg': 5000.0}, {'dep': '教学部', 'salary__avg': 51000.0}]>
'''

单表分组查询ORM语法:

1
单表模型.objects.values('group by的字段').annotate(聚合函数)

示例2

1
2
3
4
5
6
# 查询每一个省份的名称以及员工数
res2 = Emp.objects.values('province').annotate(Count('id'))
print(res2)
'''
<QuerySet [{'province': '山东省', 'id__count': 2}, {'province': '河北省', 'id__count': 1}]>
'''

补充知识点

1
2
3
4
5
6
7
8
9
10
11
12
13
# 补充
res3 = Emp.objects.all() # select * from emp;
res4 = Emp.objects.all().values('name') # select name from emp;

res5 = Emp.objects.all().values('id') # select id from emp;

# annotate之前的内容是以xxx分组(group by) 但是如果以id分组完全没意义
res6 = Emp.objects.all().values('id').annotate(Avg('salary'))

# 同理 all()代表所有数据分组 select * from emp就是 以id做分组 也是没意义的
res7 = Emp.objects.all().annotate(Avg('salary'))

# 在单表分组下 按主键进行分组是没任何意义的

在单表分组下 按主键进行分组是没任何意义的