聚合查询(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 – 多表实例(聚合与分组查询)相关推荐

  1. Django ORM – 多表实例

    文章目录 Django ORM – 多表实例 创建模型 实例 表结构 插入数据 ORM - 添加数据 一对多(外键 ForeignKey) app01/views.py 文件代码: app01/vie ...

  2. Django模型系统——ORM中跨表、聚合、分组、F、Q

    核心知识点: 1.明白表之间的关系 2.根据关联字段确定正反向,选择一种方式 在Django的ORM种,查询既可以通过查询的方向分为正向查询和反向查询,也可以通过不同的对象分为对象查询和Queryse ...

  3. Django ORM – 多表实例:Django模型Model的定义+模型间关系

    Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 我们可以根据自己业务需求选择不同的 ...

  4. Django丨ORM - 单表实例

    ORM - 单表实例 创建一个项目 django-admin.py startproject app01 在settings.py中修改INSTALLED_APPS INSTALLED_APPS = ...

  5. Django丨聚合与分组查询

    多表实例 聚合查询 聚合查询函数时对一组值执行计算,并返回单个值 Django使用聚合查询前要先从django.db.models引用Avg.Max.Min.Count.Sum(首字母大写) from ...

  6. Django丨多表实例

    ORM - 多表实例 表与表之间得关系分为三种 一对一:一个人对应一个身份证号码,数据字段设置为unique. 一对多:一个家庭有多个人,一般通过外键实现 多对多:一个学生有多门课程,一个课程有多个学 ...

  7. python一对一_Python - Django - ORM 一对一表结构

    当一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁,可以把不怎么常用的字段 单独拿出来做成一张表,然后用一对一的表关联起来 这样既保证数据都完整的保存下来,又能保证检索更快 model ...

  8. MySQL数据库——day26 数据库安装,卸载,概念,msq的介绍,安装,连接,DDL,DML,DQL模糊查询,字段控制(别名和运算),排序,聚合函数,分组查询(where和having),分页查询

    学到mysql的时候非常的快,感觉前面的没有很巩固,还是要复习前面的博客 常见的数据库 MySQL , Oracle , SQL Server , SQLite , DB2 , - SQL Serve ...

  9. Django ORM 单表操作

    默认使用sqllite数据库 创建表 # models.py form django.db import models class Book(models.Model): # 表名book,djang ...

最新文章

  1. 《LeetCode力扣练习》第617题 合并二叉树 Java
  2. Python中关于‘self’的种种用法笔记
  3. WSDM 2020 | RMRN:社区问答中的深度关联推理模型
  4. java泛型学习一:解惑继承
  5. 有道云笔记里几种我觉得比较有用的操作
  6. python免杀技术---shellcode的加载与执行
  7. linux建立动态库链接,Linux动态链接库.so文件的创建与使用
  8. hdu-5493 Queue(二分+树状数组)
  9. reactrouter4路由钩子_react router @4 和 vue路由 详解(八)vue路由守卫
  10. Hive SQL开窗函数详解
  11. 刷屏了!张一鸣6000字内部演讲:不依赖捷径,不轻言All-in(附全文)
  12. SQL Server误区30日谈-Day28-有关大容量事务日志恢复模式的误区
  13. W3Cschool导航条练习
  14. 【干货】|800份实战经验PPT免费下载
  15. html5中加下划线,为超链接添加下划线
  16. 国内和国际反垃圾邮件组织
  17. I盘显示无法访问数据错误(循环冗余检查),里面的资料怎么恢复
  18. 利用python制作拼图_用python做一个三阶拼图
  19. 怎么恢复计算机隐藏的桌面图标,怎么把桌面图标隐藏 win10桌面怎么找回我的文档图标?...
  20. html5新特性的理解

热门文章

  1. Linux网络——数据链路层
  2. 如何使用英特尔® Wi-Fi 6E (Gig+) 产品启用 Wi-Fi 6E/6GHz 频带
  3. 涂料检测实验室建设背后事项
  4. 解决启动nginx报错问题:[warn] 4450#0: the “user“ directive makes sense only if the master process runs......
  5. C#.NetWPF实现垃圾桶案例
  6. SNS:经营人与人之间的关系
  7. ZCMU--1488: 过家家。。。(C语言)
  8. 一文详解卡尔曼滤波两处噪声的来源及影响
  9. 成都百择电商:抖音平台优惠券有限制吗?
  10. 【基础】n的阶乘尾部有多少个0 JAVA金典算法-判断一个数(乘积得到的数)的末尾有几个0--发掘