Django分表操作、聚合及FQ方法
聚合
aggregate(*args, **kwargs)
# 计算所有图书的平均价格
from django.db.models import Avg
Book.objects.all().aggregate(Avg('price'))
#{'price__avg': 34.35}
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。
Book.objects.aggregate(average_price=Avg('price'))
#{'average_price': 34.35}
如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
from django.db.models import Avg, Max, Min
Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
#{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
# 查询所有书籍的平均价格
from django.db.models import Avg,Count,Max,Min
ret=Book.objects.all().aggregate(Avg('price'))
# {'price__avg': 202.896}
# 可以改名字
ret=Book.objects.all().aggregate(avg_price=Avg('price'))
# 统计平均价格和最大价格
ret=Book.objects.all().aggregate(avg_price=Avg('price'),max_price=Max('price'))
# 统计最小价格
ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price'))
# 统计个数和平均价格
ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('price'))
ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('nid'))
print(ret)
案例
分组
annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。
总结 :跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询。
查找练习
练习:统计每一本书作者个数
from django.db.models import Avg, Max, Sum, Min, Max, Count
book_list = models.Book.objects.all().annotate(author_num=Count("authors"))
for book in book_list:
print(book.name)
print(book.author_num)
book_list = models.Book.objects.all().annotate(author_num=Count("authors")).values('name','author_num')
print(book_list)
练习:统计每一个出版社的最便宜的书
publishList=Publish.objects.annotate(MinPrice=Min("book__price"))
for publish_obj in publishList:
print(publish_obj.name,publish_obj.MinPrice)
annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:
queryResult= Publish.objects.annotate(MinPrice=Min("book__price")).values_list("name","MinPrice")
print(queryResult)
练习:统计每一本以py开头的书籍的作者个数:
queryResult=Book.objects.filter(title__startswith="Py").annotate(num_authors=Count('authors'))
练习:统计不止一个作者的图书:(作者数量大于一)
ret=models.Book.objects.annotate(author_num=Count("authors")).filter(author_num__gt=1).values('name','author_num')
print(ret)
练习:根据一本图书作者数量的多少对查询集 QuerySet进行排序:
Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')
练习:查询各个作者出的书的总价格:
ret=models.Author.objects.annotate(sum_price=Sum("book__price")).values("name", "sum_price")
print(ret)
练习:查询每个出版社的名称和书籍个数
ret=models.Publish.objects.all().annotate(c=Count('book__name')).values('name','c')
print(ret)
# ————————————单表下的分组查询
'''
查询每一个部门名称以及对应的员工数
emp:
id name age salary dep
1 alex 12 2000 销售部
2 egon 22 3000 人事部
3 wen 22 5000 人事部
'''
# select count(id) from emp group by dep
# 示例一:查询每一个部门的名称,以及平均薪水
# select dep,Avg(salary) from app01_emp group by dep
from django.db.models import Avg, Count, Max, Min
ret=Emp.objects.values('dep').annotate(Avg('salary'))
# 重新命名
ret=Emp.objects.values('dep').annotate(avg_salary=Avg('salary'))
print(ret)
# ---*******单表分组查询ORM总结:表名.objects.values('group by 的字段').annotate(聚合函数('统计的字段'))
# 示例2 查询每个省份对应的员工数
ret=Emp.objects.values('province').annotate(Count('id'))
ret=Emp.objects.values('province').annotate(c=Count('id'))
print(ret)
# 补充知识点:
ret=Emp.objects.all()
# select * from emp
ret=Emp.objects.values('name')
# select name from emp
# ****单表下,按照id进行分组是没有任何意义的
ret=Emp.objects.all().annotate(Avg('salary'))
print(ret)
# ******多表分组查询
# 查询每一个出版社出版的书籍个数
ret=Book.objects.values('publish_id').annotate(Count('nid'))
print(ret)
# 查询每个出版社的名称以及出版社书的个数(先join在跨表分组)
# 正向
ret=Publish.objects.values('name').annotate(Count('book__name'))
ret=Publish.objects.values('nid').annotate(c=Count('book__name')).values('name','c')
print(ret)
# 反向
ret=Book.objects.values('publish__name').annotate(Count('name'))
ret=Book.objects.values('publish__name').annotate(c=Count('name')).values('publish__name','c')
print(ret)
# 查询每个作者的名字,以及出版过书籍的最高价格
ret=Author.objects.values('pk').annotate(c=Max('book__price')).values('name','c')
print(ret)
# 跨表查询的模型:每一个后表模型.objects.value('pk').annotate(聚合函数('关联表__统计字段')).values() # 查询每一个书籍的名称,以及对应的作者个数
ret=Book.objects.values('pk').annotate(c=Count('authors__name')).values('name','c')
print(ret)
# 统计不止一个作者的图书
ret=Book.objects.values('pk').annotate(c=Count('authors__name')).filter(c__gt=1).values('name','c')
print(ret)
F查询与Q查询
F查询
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
# 查询评论数大于收藏数的书籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
# 查询评论数大于收藏数2倍的书籍
Book.objects.filter(commnetNum__lt=F('keepNum')*2)
修改操作也可以使用F函数,比如将每一本书的价格提高30元:
Book.objects.all().update(price=F("price")+30)
Q查询
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。
from django.db.models import Q
Q(title__startswith='Py')
Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。
bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
等同于下面的SQL WHERE 子句:
WHERE name ="yuan" OR name ="egon"
你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:
查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:
bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017), title__icontains="python")
# 查询评论数大于阅读数的书籍
from django.db.models import F,Q
# select * from book where commit_num>read_num;
# 这样肯定是不行的
# Book.objects.filter(commit_num__gt=read_num)
ret=Book.objects.filter(commit_num__gt=F('reat_num'))
print(ret)
# 把所有书籍的价格加10
Book.objects.all().update(price=F('price')+10)
# ----Q函数,描述一个与,或,非的关系
# 查询名字叫红楼梦或者价格大于100的书
ret=Book.objects.filter(Q(name='红楼梦')|Q(price__gt=100))
print(ret)
# 查询名字叫红楼梦和价格大于100的书
ret = Book.objects.filter(Q(name='红楼梦') & Q(price__gt=100))
print(ret)
# # 等同于
ret2=Book.objects.filter(name='红楼梦',price__gt=100)
print(ret2)
# 也可以Q套Q
# 查询名字叫红楼梦和价格大于100 或者 nid大于2
ret=Book.objects.filter((Q(name='红楼梦') & Q(price__gt=100))|Q(nid__gt=2))
print(ret)
# ----非
ret=Book.objects.filter(~Q(name='红楼梦'))
print(ret)
# Q和键值对联合使用,但是键值对必须放在Q的后面(描述的是一个且的关系)
# 查询名字不是红楼梦,并且价格大于100的书
ret=Book.objects.filter(~Q(name='红楼梦'),price__gt=100)
print(ret)
Django分表操作、聚合及FQ方法的更多相关文章
- Django之ORM操作(聚合 分组、F Q)
Django之ORM操作(聚合 分组.F Q) 聚合 aggregate()是QuerySet的一个终止子句,也就是说,他返回一个包含一些键值对的字典,在它的后面不可以再进行点(.)操作. 键的名 ...
- mysql分表操作
一般分表操作有垂直拆分和水平拆分.顾名思义. 1. 垂直拆分是指,这个表的列,即字段,要拆分成两个或多个表. 这个应用场景比如:这个表字段,几个都是int.datetime等,有那么一个是text类 ...
- Mycat本地模式的自增长分表操作
Mycat对表t_rc_rule_monitor做分表操作 在mysql上执行(没有t_rc_rule_monitor) DROP TABLE IF EXISTS t_rc_rule_monitor; ...
- zabbix 数据库分表操作
近期zabbix数据库占用的io高,在页面查看图形很慢,而且数据表已经很大,将采用把数据库的数据目录移到新的磁盘,将几个大表进行分表操作 一.数据迁移: 1.数据同步到新的磁盘上,先停止mysql(不 ...
- mysql分表场景分析与简单分表操作
为什么要分表 首先要知道什么情况下,才需要分表个人觉得单表记录条数达到百万到千万级别时就要使用分表了,分表的目的就在于此,减小数据库的负担,缩短查询时间. 表分割有两种方式: 1水平分割:根据一列或多 ...
- MyBatis实现Mysql数据库分库分表操作和总结
前言 作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移,总有一天,数据量会大到一个难以处理的地步.这时仅仅一张表的数据就已经超过了千万,无论是查询还是修改,对于它的操作都会很耗时,这 ...
- Django单表操作
一.数据库相关设置 配置ORM的loggers日志: # 配置ORM的loggers日志 LOGGING = { 'version': 1, 'disable_existing_loggers': F ...
- Django 多表查询 聚合查询 分组查询 F查询 Q查询
# -------------------------------------------------------------------------------------------------- ...
- Django多表操作
多表创建 创建模型 下面通过一个简单的图书管理系统,来阐述多表的创建和查询操作 在视图函数里里定义如下代码 from django.db import models class Book(models ...
随机推荐
- tomcat常见报错解决方法汇总
报错一:内存泄漏,字眼This is very likely to create a memory leak. 解决方法:修改tomcat内存. 在tomcat/bin目录下,修改catalina.s ...
- [LeetCode] 482. License Key Formatting 注册码格式化
You are given a license key represented as a string S which consists only alphanumeric character and ...
- windows中怎么添加定时任务
linux中有crontab定时任务,很方便 其实windows也有类似的 需求:定时执行python脚本 1.Windows键+R,调出此窗口,输入compmgmt.msc 2. 每分钟都执行一次脚 ...
- IFC文件介绍
IFC是一个数据交换标准, 用于不同系统交换和共享数据. IFC是采用EXPRESS语言定义的实体关系模型,由几百个实体对象组成.实体对象包括建筑要素如IfcWall,几何元素如IfcExtruded ...
- IDEA 2019 注册码
CATF44LT7C-eyJsaWNlbnNlSWQiOiJDQVRGNDRMVDdDIiwibGljZW5zZWVOYW1lIjoiVmxhZGlzbGF2IEtvdmFsZW5rbyIsImFz ...
- ContainsExtensions不分区大小写
public static class ContainsExtensions { public static bool Contains(this string source, string valu ...
- Pair(二进制处理+数位dp)(2019牛客暑期多校训练营(第七场))
示例: 输入: 33 4 24 5 27 8 5 输出:5 7 31 题意:存在多少对<x,y>满足x&y>C或x^y<C的条件.(0<x<=A,0< ...
- 【Linux】一步一步学Linux——Linux系统目录详解(09)
目录 00. 目录 01. 文件系统介绍 02. 常用目录介绍 03. /etc目录文件 04. /dev目录文件 05. /usr目录文件 06. /var目录文件 07. /proc 08. 比较 ...
- A Simple Question of Chemistry
#include<stdio.h> int main() { int i, l; ]; ]; l = ; ) { l++; } ; a[i]!= && i<l; i+ ...
- Flask总结篇
1 Flask框架的优势? 相信做Python这一块的程序员都有听说这三个框架,就像神一样的存在,每一个框架的介绍我就不写出来了,感兴趣可以自己百度了解了解!下面我就说正事 Django:Python ...