Django ORM – 多表实例(聚合与分组查询)
聚合查询(aggregate)
聚合查询函数是对一组值执行计算,并返回单个值。
聚合查询返回值的数据类型是字典。
聚合函数 aggregate() 是 QuerySet 的一个终止子句, 生成的一个汇总值,相当于 count()。
使用 aggregate() 后,数据类型就变为字典,不能再使用 QuerySet 数据类型的一些 API 了。
日期数据类型(DateField)可以用 Max 和 Min。
Django 使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum(首字母大写)。
from django.db.models import Avg,Max,Min,Count,Sum # 引入函数
maxAge = Student.objects.aggregate(Max('s_age'))
minAge = Studen.objects.aggregate(Min('s_age'))
sumAge = Studen.objects.aggregate(Sum('s_age'))
avgAge = Studen.objects.aggregate(Avg('s_age'))
countAge = Studen.objects.aggregate(Count('s_age'))
分组查询(annotate)
分组查询一般会用到聚合函数,所以使用前要先从 django.db.models 引入 Avg,Max,Min,Count,Sum(首字母大写)。
from django.db.models import Avg,Max,Min,Count,Sum # 引入函数
返回值:
- 分组后,用 values 取值,则返回值是 QuerySet 数据类型里面为一个个字典;
- 分组后,用 values_list 取值,则返回值是 QuerySet 数据类型里面为一个个元组。
MySQL 中的 limit 相当于 ORM 中的 QuerySet 数据类型的切片。
注意:
annotate 里面放聚合函数。
values 或者 values_list 放在 annotate 前面:values 或者 values_list 是声明以什么字段分组,annotate 执行分组。
values 或者 values_list 放在annotate后面: annotate 表示直接以当前表的pk执行分组,values 或者 values_list 表示查询哪些字段, 并且要将 annotate 里的聚合函数起别名,在 values 或者 values_list 里写其别名。
准备数据和创建模型:models.py
数据:在 MySQL 命令行中执行:
统计每一个出版社的最便宜的书的价格:
values 或者 values_list 放在 annotate 前面:values 或者 values_list 是声明以什么字段分组,annotate 执行分组。
res = models.Publish.objects.values("name").annotate(in_price = Min("book__price"))
print(res)
命令行中可以看到以下输出:
<QuerySet [{'name': '菜鸟出版社', 'in_price': Decimal('100.00')}, {'name': '明教出版社', 'in_price': Decimal('300.00')}]>
统计每一本书的作者个数:
values 或者 values_list 放在annotate后面: annotate 表示直接以当前表的pk执行分组,values 或者 values_list 表示查询哪些字段, 并且要将 annotate 里的聚合函数起别名,在 values 或者 values_list 里写其别名。
res = models.Book.objects.annotate(c = Count("authors__name")).values("title","c")
print(res)
命令行中可以看到以下输出:
<QuerySet [{'title': '菜鸟教程', 'c': 1}, {'title': '吸星大法', 'c': 1}, {'title': '冲灵剑法', 'c': 1}]>
统计每一本以"菜"开头的书籍的作者个数:
res = models.Book.objects.filter(title__startswith="菜").annotate(c = Count("authors__name")).values("title","c")
print(res)
统计不止一个作者的图书名称:
res = models.Book.objects.annotate(c = Count("authors__name")).filter(c__gt=0).values("title","c")
print(res)
命令行中可以看到以下输出:
<QuerySet [{'title': '菜鸟教程', 'c': 1}, {'title': '吸星大法', 'c': 1}, {'title': '冲灵剑法', 'c': 1}]>
根据一本图书作者数量的多少对查询集 QuerySet 进行降序排序:
res = models.Book.objects.annotate(c = Count("authors__name")).order_by("-c").values("title","c")
print(res)
查询各个作者出的书的总价格:
res = models.Author.objects.annotate(all = Sum("book__price")).values("name","all")
print(res)
F() 查询
F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
之前构造的过滤器都只是将字段值与某个常量做比较,如果想要对两个字段的值做比较,就需要用到 F()。
使用前要先从 django.db.models 引入 F:
from django.db.models import F
用法:
F("字段名称")
F 动态获取对象字段的值,可以进行运算。
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取余的操作。
修改操作(update)也可以使用 F() 函数。
查询工资大于年龄的人:
from django.db.models import F
...
book=models.Emp.objects.filter(salary__gt=F("age")).values("name","age")
...
将每一本书的价格提高100元:
res = models.Book.objects.update(price=F("price")+100)
print(res)
from django.db.models import F
Studen.objects.filter(pk__gte=F('s_age')) # 查询学生中主键大于年龄的学生
Studen.objects.filter(pk__gt=F('s_age')+20) # 查询学生中主键大于年龄加20的学生
Q() 查询
使用前要先从 django.db.models 引入 Q:
from django.db.models import Q
用法:
Q(条件判断)
例如:Q(title__startswith="菜")
之前构造的过滤器里的多个条件的关系都是 and,如果需要执行更复杂的查询(例如 or 语句),就可以使用 Q 。
Q 对象可以使用 & | ~ (与 或 非)操作符进行组合。
优先级从高到低:~ & |。
可以混合使用 Q 对象和关键字参数,Q 对象和关键字参数是用"and"拼在一起的(即将逗号看成 and ),但是 Q 对象必须位于所有关键字参数的前面。
查询价格大于 350 或者名称以菜开头的书籍的名称和价格。
from django.db.models import Q
...
res=models.Book.objects.filter(Q(price__gt=350)|Q(title__startswith="菜")).values("title","price")
print(res)
...
查询以"菜"结尾或者不是 2010 年 10 月份的书籍:
res = models.Book.objects.filter(Q(title__endswith="菜") | ~Q(Q(pub_date__year=2010) & Q(pub_date__month=10)))
print(res)
查询出版日期是 2004 或者 1999 年,并且书名中包含有"菜"的书籍。
Q 对象和关键字混合使用,Q 对象要在所有关键字的前面:
res = models.Book.objects.filter(Q(pub_date__year=2004) | Q(pub_date__year=1999), title__contains="菜")
print(res)
Django ORM – 多表实例(聚合与分组查询)相关推荐
- Django ORM – 多表实例
文章目录 Django ORM – 多表实例 创建模型 实例 表结构 插入数据 ORM - 添加数据 一对多(外键 ForeignKey) app01/views.py 文件代码: app01/vie ...
- Django模型系统——ORM中跨表、聚合、分组、F、Q
核心知识点: 1.明白表之间的关系 2.根据关联字段确定正反向,选择一种方式 在Django的ORM种,查询既可以通过查询的方向分为正向查询和反向查询,也可以通过不同的对象分为对象查询和Queryse ...
- Django ORM – 多表实例:Django模型Model的定义+模型间关系
Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 我们可以根据自己业务需求选择不同的 ...
- Django丨ORM - 单表实例
ORM - 单表实例 创建一个项目 django-admin.py startproject app01 在settings.py中修改INSTALLED_APPS INSTALLED_APPS = ...
- Django丨聚合与分组查询
多表实例 聚合查询 聚合查询函数时对一组值执行计算,并返回单个值 Django使用聚合查询前要先从django.db.models引用Avg.Max.Min.Count.Sum(首字母大写) from ...
- Django丨多表实例
ORM - 多表实例 表与表之间得关系分为三种 一对一:一个人对应一个身份证号码,数据字段设置为unique. 一对多:一个家庭有多个人,一般通过外键实现 多对多:一个学生有多门课程,一个课程有多个学 ...
- python一对一_Python - Django - ORM 一对一表结构
当一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁,可以把不怎么常用的字段 单独拿出来做成一张表,然后用一对一的表关联起来 这样既保证数据都完整的保存下来,又能保证检索更快 model ...
- MySQL数据库——day26 数据库安装,卸载,概念,msq的介绍,安装,连接,DDL,DML,DQL模糊查询,字段控制(别名和运算),排序,聚合函数,分组查询(where和having),分页查询
学到mysql的时候非常的快,感觉前面的没有很巩固,还是要复习前面的博客 常见的数据库 MySQL , Oracle , SQL Server , SQLite , DB2 , - SQL Serve ...
- Django ORM 单表操作
默认使用sqllite数据库 创建表 # models.py form django.db import models class Book(models.Model): # 表名book,djang ...
最新文章
- 《LeetCode力扣练习》第617题 合并二叉树 Java
- Python中关于‘self’的种种用法笔记
- WSDM 2020 | RMRN:社区问答中的深度关联推理模型
- java泛型学习一:解惑继承
- 有道云笔记里几种我觉得比较有用的操作
- python免杀技术---shellcode的加载与执行
- linux建立动态库链接,Linux动态链接库.so文件的创建与使用
- hdu-5493 Queue(二分+树状数组)
- reactrouter4路由钩子_react router @4 和 vue路由 详解(八)vue路由守卫
- Hive SQL开窗函数详解
- 刷屏了!张一鸣6000字内部演讲:不依赖捷径,不轻言All-in(附全文)
- SQL Server误区30日谈-Day28-有关大容量事务日志恢复模式的误区
- W3Cschool导航条练习
- 【干货】|800份实战经验PPT免费下载
- html5中加下划线,为超链接添加下划线
- 国内和国际反垃圾邮件组织
- I盘显示无法访问数据错误(循环冗余检查),里面的资料怎么恢复
- 利用python制作拼图_用python做一个三阶拼图
- 怎么恢复计算机隐藏的桌面图标,怎么把桌面图标隐藏 win10桌面怎么找回我的文档图标?...
- html5新特性的理解
热门文章
- Linux网络——数据链路层
- 如何使用英特尔® Wi-Fi 6E (Gig+) 产品启用 Wi-Fi 6E/6GHz 频带
- 涂料检测实验室建设背后事项
- 解决启动nginx报错问题:[warn] 4450#0: the “user“ directive makes sense only if the master process runs......
- C#.NetWPF实现垃圾桶案例
- SNS:经营人与人之间的关系
- ZCMU--1488: 过家家。。。(C语言)
- 一文详解卡尔曼滤波两处噪声的来源及影响
- 成都百择电商:抖音平台优惠券有限制吗?
- 【基础】n的阶乘尾部有多少个0 JAVA金典算法-判断一个数(乘积得到的数)的末尾有几个0--发掘