注意:
本实验是接着 《Django 自定义逻辑添加(通过自定义 save 对象实现)(一次性完成多对多表数据的插入)》而继续的
正文:
步骤一:进入相应的 Django 环境
(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *
步骤二:插入测试数据
>>> user = Student(sname='zhangsan',score=60,cls=Clazz(cname='Class1'))
>>> user.save()
>>> user = Student(sname='lisi',score=80,cls=Clazz(cname='Class1'))
>>> user.save()
>>> user = Student(sname='wangwu',score=90,cls=Clazz(cname='Class1'))
>>> user.save()
>>> user = Student(sname='zhaoliu',score=70,cls=Clazz(cname='Class1'))
>>> user.save()
>>> user = Student(sname='xueer',score=70,cls=Clazz(cname='Class2'))
>>> user.save()
>>> user = Student(sname='huangyi',score=70,cls=Clazz(cname='Class2'))
>>> user.save()
(补充:这里以随机插入 6 条测试数据为例)
步骤三:设置 1 个显示上 1 句 SQL 语句的函数
>>> def showsql():
... from django.db import connection
... print(connection.queries[-1]['sql'])
(补充:这里的 [-1] 是指显示上一条操作的 SQL 语句)
步骤四:通过聚合函数查询所需的数值
4.1 通过聚合函数查询最大值
4.1.1 导入聚合函数最大值模块
>>> from django.db.models import Max
4.1.2 通过聚合函数查询最大值(显示默认解释说明)
4.1.2.1 通过聚合函数查询最大值(显示默认解释说明)
>>> Student.objects.aggregate(Max('score'))
{'score__max': 90}
(
补充:
1) 这里以查询所有数据 score 字段的最大值为例
2) 这里查出的最大值是 90
)
4.1.2.2 显示通过聚合函数查询最大值的 SQL 语句(显示默认解释说明)
>>> showsql()
SELECT MAX(`user_student`.`score`) AS `score__max` FROM `user_student`
(补充:这里以查询所有数据 score 字段的最大值为例)
4.1.3 通过聚合函数查询最大值(显示自定义解释说明)
4.1.3.1 通过聚合函数查询最大值(显示自定义解释说明)
>>> Student.objects.aggregate(m=Max('score'))
{'m': 90}
(
补充:
1) 这里以查询所有数据 score 字段的最大值为例
2) 查出的最大值是 90
3) 这里显示的自定义解释说明是 m
)
4.1.3.2 显示通过聚合函数查询最大值的 SQL 语句(显示自定义解释说明)
>>> showsql()
SELECT MAX(`user_student`.`score`) AS `m` FROM `user_student`
(
补充:
1) 这里以查询所有数据 score 字段的最大值为例
2) 这里显示的自定义解释说明是 m
)
4.2 通过聚合函数查询最小值
4.2.1 导入聚合函数最小值模块
>>> from django.db.models import Min
4.2.2 通过聚合函数查询最小值
>>> Student.objects.aggregate(Min('score'))
{'score__min': 60}
(
补充:
1) 这里以查询所有数据 score 字段的最小值为例
2) 这里查出的最小值是 60
)
4.2.3 显示通过聚合函数查询最小值的 SQL 语句
>>> showsql()
SELECT MIN(`user_student`.`score`) AS `score__min` FROM `user_student`
(补充:这里以查询所有数据 score 字段的最小值为例)
4.3 通过聚合函数统计数据条数
4.3.1 导入聚合函数统计数据条数的模块
>>> from django.db.models import *
4.3.2 通过聚合函数统计数据条数(统计所有数据的条数)
4.3.2.1 通过聚合函数统计数据条数(统计所有数据的条数)
>>> Student.objects.aggregate(c=Count('*'))
{'c': 6}
(
补充:
1) 这里统计所有数据的数据总条数为例
2) 这里显示的自定义解释说明是 c
3) 这里查出的数据条数是 6
)
4.3.2.2 显示通过聚合函数统计数据条数的 SQL 语句(统计所有数据的条数)
>>> showsql()
SELECT COUNT(*) AS `c` FROM `user_student`
(
补充:
1) 这里统计所有数据的数据总条数为例
2) 这里显示的自定义解释说明是 c
)
4.3.3 通过聚合函数统计数据条数(统计包含某字段数据的条数)
4.3.3.1 通过聚合函数统计数据条数(统计包含某字段数据的条数)
>>> Student.objects.aggregate(c=Count('score'))
{'c': 6}
(
补充:
1) 这里以统计包含 score 字段的数据总条数为例
2) 这里显示的自定义解释说明是 c
3) 这里查出的数据条数是 6
)
4.3.3.2 显示通过聚合函数统计数据条数的 SQL 语句(统计包含某字段数据的条数)
>>> showsql()
SELECT COUNT(`user_student`.`score`) AS `c` FROM `user_student`
(
补充:
1) 这里以统计包含 score 字段的数据总条数为例
2) 这里显示的自定义解释说明是 c
)
4.4 通过聚合函数求和
4.4.1 导入聚合函数求和的模块
>>> from django.db.models import *
4.4.2 通过聚合函数求和
>>> Student.objects.aggregate(Sum('score'))
{'score__sum': 440}
(
补充:
1) 这里以求所有数据 score 字段的值的和为例
2) 这里求出的和是 440
)
4.4.3 显示通过聚合函数求和的 SQL 语句
>>> showsql()
SELECT SUM(`user_student`.`score`) AS `score__sum` FROM `user_student`
(补充:这里以求所有数据 score 字段的值的和为例)
4.5 通过聚合函数求平均数
4.5.1 导入聚合函数求平均数的模块
>>> from django.db.models import *
4.5.2 通过聚合函数求平均值
>>> Student.objects.aggregate(Avg('score'))
{'score__avg': 73.3333}
(
补充:
1) 这里以求所有数据 score 字段的平均值为例
2) 这里求出的平均值是 73.3333
)
4.5.3 显示通过聚合函数求平均值的 SQL 语句
>>> showsql()
SELECT AVG(`user_student`.`score`) AS `score__avg` FROM `user_student`
(补充:这里以求所有数据 score 字段的平均值为例)
步骤五:通过分组聚合函数查询所需的数值
5.1 导入分组聚合函数模块
>>> from django.db.models import *
5.2 通过分组聚合函数统计每组数据的条数
5.2.1 通过分组聚合函数统计每组数据的条数
>>> Student.objects.values('cls').annotate(c=Count('score'))
<QuerySet [{'cls': 1, 'c': 4}, {'cls': 2, 'c': 2}]>
(
补充:
1) 这里以 cls 字段进行分组,统计每组包含 score 字段数据的条数为例
2) 这里显示的自定义解释说明是 c
3) 这里求出 cls 字段值为 1 的组包含 score 字段的数据有 4 条,cls 字段的值为 2 的组包含 score 字段的数据有 2 条
)
5.2.2 显示通过分组聚合函数统计每组数据条数的 SQL 语句
>>> showsql()
SELECT `user_student`.`cls_id`, COUNT(`user_student`.`score`) AS `c` FROM `user_student` GROUP BY `user_student`.`cls_id` ORDER BY NULL LIMIT 21
(
补充:
1) 这里以 cls 字段进行分组,统计每组包含 score 字段数据的条数为例
2) 这里显示的自定义解释说明是 c
)
5.3 通过分组聚合函数统计求每组数据的平均值
5.3.1 通过分组聚合函数统计求每组数据的平均值
>>> Student.objects.values('cls').annotate(a=Avg('score'))
<QuerySet [{'cls': 1, 'a': 75.0}, {'cls': 2, 'a': 70.0}]>
(
补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的平均值为例
2) 这里显示的自定义解释说明是 a
3) 这里求出 cls 字段值为 1 的组 score 字段的平均值为 75.0,cls 字段的值为 2 的组 score 字段的平均值为 70.0
)
5.3.2 显示通过分组聚合函数统计求每组数据的平均值的 SQL 语句
>>> showsql()
SELECT `user_student`.`cls_id`, AVG(`user_student`.`score`) AS `a` FROM `user_student` GROUP BY `user_student`.`cls_id` ORDER BY NULL LIMIT 21
(
补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的平均值为例
2) 这里显示的自定义解释说明是 a
)
步骤六:通过子查询查询所需的数值
6.1 导入子查询模块
>>> from django.db.models import *
6.2 通过子查询查询总值最大的 1 组数据的总值
6.2.1 通过子查询查询总值最大的 1 组数据的总值
>>> Student.objects.values('cls').annotate(s=Sum('score')).aggregate(m=Max('s'))
{'m': 300}
(
补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的总值,再将其求和为例
2) 这里显示的自定义解释说明是 m
3) 这里求出 score 字段的总值为 300
4) values 和 annotate 一起使用时 values 则发挥的是 group by 的作用
5) values 单独使用时 values 发挥的是部分查询的作用
)
6.2.2 显示通过子查询查询总值最大的 1 组数据总值的 SQL 语句
>>> showsql()
SELECT MAX(`s`) FROM (SELECT `user_student`.`cls_id` AS Col1, SUM(`user_student`.`score`) AS `s` FROM `user_student` GROUP BY `user_student`.`cls_id` ORDER BY NULL) subquery
(
补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的总值,再将其求和为例
2) 这里显示的自定义解释说明是 m
3) values 和 annotate 一起使用时 values 则发挥的是 group by 的作用
4) values 单独使用时 values 发挥的是部分查询的作用
)
步骤七:通过关联查询查询所需的数值
7.1 导入关联查询模块
>>> from django.db.models import *
7.2 通过关联查询查询关联的数据
7.2.1 通过关联查询查询关联的数据(查询数据表中的非外键字段)
7.2.1.1 通过关联查询查询关联的数据(查询数据表中的非外键字段)
>>> Student.objects.values('cls__cname')
<QuerySet [{'cls__cname': 'Class1'}, {'cls__cname': 'Class1'}, {'cls__cname': 'Class1'}, {'cls__cname': 'Class1'}, {'cls__cname': 'Class2'}, {'cls__cname': 'Class2'}]>
(
补充:
1) 这里查出了 4 条 cls__cname 为 Class1 的数据和 2 条 cls__cname 为 Class 2 的数据
2) 这里的 cls 是 Django 数据模型类中两张数据表的外键字段,但是 cname 并不是数据库中两张数据表的外键字段
)
7.2.1.2 通过关联查询查询关联数据的 SQL 语句(查询数据表中的非外键字段)
>>> showsql()
SELECT `user_clazz`.`cname` FROM `user_student` INNER JOIN `user_clazz` ON (`user_student`.`cls_id` = `user_clazz`.`id`) LIMIT 21
(补充:这里的 cls_id 是 user_student 表中关联 user_clazz 表中 id 字段的外键字段)
7.2.2 通过关联查询查询关联的数据(查询数据表中的外键字段)
7.2.2.1 通过关联查询查询关联的数据(查询数据表中的外键字段)
>>> Student.objects.values('cls__id')
<QuerySet [{'cls__id': 1}, {'cls__id': 1}, {'cls__id': 1}, {'cls__id': 1}, {'cls__id': 2}, {'cls__id': 2}]>
(
补充:
1) 这里查出了 4 条 cls__id 为 1 的数据和 2 条 cls__id 为 2 的数据
2) 这里的 cls 是 Django 数据模型类中两张数据表的外键字段,并且 id 也是数据库中两张数据表的外键字段
)
7.2.2.2 通过关联查询查询关联数据的 SQL 语句(查询数据表中的外键字段)
>>> showsql()
SELECT `user_student`.`cls_id` FROM `user_student` LIMIT 21
(补充:这里的 cls_id 是 user_student 表中关联 user_clazz 表中 id 字段的外键字段)
步骤八:退出相应的 Django 环境
>>> quit()
步骤九:Django 聚合函数查询、分组聚合函数查询、子查询、关联查询的总结
1) 单独用 aggregate 则代表单独使用聚合函数
2) 单独用 annotate 则代表单独使用分组聚合函数
3) 在 annotate 前面加上 values 则是指定某一个字段进行分组,values.annotate