美文网首页
Django ORM – 多表实例(聚合与分组查询)

Django ORM – 多表实例(聚合与分组查询)

作者: Mister_Leo | 来源:发表于2024-09-10 16:54 被阅读0次

聚合查询(aggregate)

聚合查询函数是对一组值执行计算,并返回单个值。

有表结构如下:

id title price publish_id pub_date
3 菜鸟教程 200.00 1 2010-10-10
4 冲灵剑法 100.00 1 2004-04-04

detail.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ res }}
</body>
</html>

计算所有图书的平均价格:

from django.db.models import Avg,Max,Min,Count,Sum  #   引入函数
...
def add_book(request):
    res = models.Book.objects.aggregate(Avg("price"))
    return render(request, "detail.html", {"res": res});

// 输出:{'price__avg': Decimal('150.000000')}

计算所有图书的数量、最贵价格和最便宜价格:

res=models.Book.objects.aggregate(c=Count("id"),max=Max("price"),min=Min("price"))
// 输出:{'c': 2, 'max': Decimal('200.00'), 'min': Decimal('100.00')}

小结:

  1. 聚合查询返回值的数据类型是字典。不能再使用 QuerySet 数据类型的一些 API 了。
  2. 聚合函数 aggregate() 是 QuerySet 的一个终止子句, 生成的一个汇总值,相当于 count()。日期数据类型(DateField)可以用 Max 和 Min。
  3. 返回的字典中:键的名称默认是(属性名称加上__聚合函数名),值是计算出来的聚合值。
    如果要自定义返回字典的键的名称,可以起别名:
    aggregate(别名 = 聚合函数名("属性名称"))

分组查询(annotate)

分组查询一般会用到聚合函数。

返回值:

  1. 分组后,用 values 取值,则返回值是 QuerySet 数据类型里面为一个个字典
  2. 分组后,用values_list取值,则返回值是 QuerySet 数据类型里面为一个个元组
    MySQL 中的 limit 相当于 ORM 中的 QuerySet 数据类型的切片。

annotate 里面放聚合函数。

  1. values 或者 values_list 放在 annotate 前面:values 或者 values_list 是声明以什么字段分组,annotate 执行分组。
  2. values 或者 values_list 放在annotate后面: annotate 表示直接以当前表的pk执行分组,values 或者 values_list 表示查询哪些字段, 并且要将 annotate 里的聚合函数起别名,在 values 或者 values_list 里写其别名。

统计每一个出版社的最便宜的书的价格:

res = models.Publish.objects.values("name").annotate(in_price = Min("book__price"))

// 输出:<QuerySet [{'name': '华山出版社', 'in_price': Decimal('100.00')}, {'name': '明教出版社', 'in_price': None}]>

统计每一本书的作者个数1:

res = models.Book.objects.annotate(c = Count("authors__name")).values("title","c")
// 输出:<QuerySet [{'title': '菜鸟教程', 'c': 2}, {'title': '冲灵剑法', 'c': 1}]>

统计每一本书的作者个数2:values_list

res = models.Book.objects.annotate(c = Count("authors__name")).values_list("title","c")
// 输出:<QuerySet [('菜鸟教程', 2), ('冲灵剑法', 1)]>

统计每一本以"菜"开头的书籍的作者个数:

models.Book.objects.filter(title__startswith="菜").annotate(c = Count("authors__name")).values("title","c")
// 输出:<QuerySet [{'title': '菜鸟教程', 'c': 2}]>

统计不止一个作者的图书名称:

res = models.Book.objects.annotate(c = Count("authors__name")).filter(c__gt=1).values("title","c")
// 输出:<QuerySet [{'title': '菜鸟教程', 'c': 2}]>

根据一本图书作者数量的多少对查询集 QuerySet 进行降序排序:

res = models.Book.objects.annotate(c = Count("authors__name")).order_by("-c").values("title","c")
// 输出:<QuerySet [{'title': '菜鸟教程', 'c': 2}, {'title': '冲灵剑法', 'c': 1}]>

查询各个作者出的书的总价格:

res = models.Author.objects.annotate(all = Sum("book__price")).values("name","all")
// 输出:<QuerySet [{'name': '令狐冲', 'all': Decimal('300.00')}, {'name': '任我行', 'all': None}, {'name': '任盈盈', 'all': Decimal('200.00')}]>

小结:

  1. 使用 values => 字典,values_list => 元祖。
  2. value(或 value_list)在前,以values声明的字段分组,在后以pk分组。

F() 查询

F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

F 动态获取对象字段的值,可以进行运算。
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取余的操作。
修改操作(update)也可以使用 F() 函数。

查询工资大于年龄的人:

from django.db.models import F
...
res = models.Emp.objects.filter(salary__gt=F("age")).values("name","age")
...

将每一本书的价格提高100元:

res = models.Book.objects.update(price=F("price")+100)

Q() 查询

Q(条件判断)
Q 对象可以使用 & | ~ (与 或 非)操作符进行组合。

查询价格小于 150 或者名称以菜开头的书籍的名称和价格。

rom django.db.models import Q
...
res=models.Book.objects.filter(Q(price__lt=150)|Q(title__startswith="菜")).values("title","price")
// 输出:<QuerySet [{'title': '菜鸟教程', 'price': Decimal('200.00')}, {'title': '冲灵剑法', 'price': Decimal('100.00')}]>

查询以"菜"结尾或者不是 2010 年 10 月份的书籍:

res = models.Book.objects.filter(Q(title__endswith="菜") | ~Q(Q(pub_date__year=2010) & Q(pub_date__month=10)))
// 输出:<QuerySet [{'title': '冲灵剑法', 'price': Decimal('100.00')}]>

查询出版日期是 2004 或者 1999 年,并且书名中包含有"菜"的书籍。
Q 对象和关键字混合使用,Q 对象要在所有关键字的前面:

res = models.Book.objects.filter(Q(pub_date__year=2004) | Q(pub_date__year=1999), title__contains="菜")

相关文章

  • django orm分组聚合

    annotate分组 aggregate聚合 很简单就是查询一个数据集的某个字段的最大值、最小值、平均数、求和、计...

  • Django 中的聚合查询与分组查询

    聚合 常用的聚合函数 Avg, Max, Min 实例1 实例2 分组 emp表模型 总结 :跨表分组查询本质就...

  • Django orm多表查询优化

    1.基本操作 2.Foreign key的使用原因 下面两个 取到的是对象,并且注意 取到的对象可以 获取其他字段...

  • MySQL约束课堂笔记

    今日内容 一、DQL:查询语句2、排序查询3、聚合函数4、分组查询5、分页查询二、约束三、多表之间的关系 DQL:...

  • Python MySQL数据库2:数据库查询

    总体内容 一、数据准备、基本的查询 二、条件查询 三、排序 四、聚合、分组 五、分页 六、连接查询(多表的时候有用...

  • Mysql 1.数据库进阶

    1.DQL:查询语句排序查询聚合函数分组查询分页查询2.约束3.多表之间的联系4.范式5.数据库的备份与还原 排序...

  • MySQL-6:查询语句

    1、DQL:查询语句: 1.排序查询 2.聚合函数 3.分组查询 4.分页查询 2、约束3、多表之间的关系4、范式...

  • Django聚合查询及分组查询

    导入聚合函数方法 聚合查询查询所有书籍的数量 上面的方法执行返回的结果是一个字典,其中sum作为键,查询结果作为值...

  • Django模型层之多表操作(五)之聚合查询与分组查询

    聚合查询与分组查询 聚合 aggregate(*args, **kwargs) 计算所有图书的平均价格 from ...

  • mysql 基础知识

    3, 数据库的考点:多表联查,聚合函数和分组, 自查询 1. 简述数据库查询语句中,内连接inner join ,...

网友评论

      本文标题:Django ORM – 多表实例(聚合与分组查询)

      本文链接:https://www.haomeiwen.com/subject/egfuljtx.html