常见的聚合函数有: sum avg min max count
聚合函数可以单独使用,不一定要和分组配合使用:只不过聚合函数与group by搭配使用
统计每个部门有多少人: 原生sql:select count(name) from emp; 引入聚合函数 from django.db.models import Avg,Count,Sum,Min,Max orm:
models.Book.objects.all().aggregate(Avg("price"))
结果为:{'price__sum':'2158.00'}
也可以自定义key,相当于sql中的as别名
models.Book.objects.all().aggregate(avgprice=Avg("price"))
结果为:{'avgprice':'2158.00'}
注意aggregate返回结果是个字典,是queryset的终止语句。(查询api返回结果都是queryset所以能一直点 "." 下去。
#统计每一本书的作者个数 select book.id ,book.title,count(1) from book join bookAuthor on book,id=bookAuthor.book_id group by book.id,book.title; models.Book.objects.all().annotate(Count("authors")) #统计每一本书的价格,annotate返回结果queryset #all可以得出[book_obj1,book_obj2,book_obj3]annotate对每一组进行统计,统计每组price的和 ret=models.Book.objects.all().annotate(c=sum("price")) for obj in ret: print(obj.title,obj.c)
#查询每一个出版社出版过的所有书籍的总价格 models.Publish.objects.all().annotate(Sum("bookList__price"))
方式二:values相当于group by分组条件,annotate会将重复对象合并为一个组,
models.Book.objects.all().values("publisher__name").annotate(Sum("price"))
FQ查询
我们给book表添加俩个字段comment_num评论数,read_num阅读数
F查询
引入 from django.db.models import F,Q
#查询评论大于50的书 models.Book.objects.filter(comment_um__gt=50) #查询评论数大于阅读数的书,当等于后面为一个变量时使用F获取变量的值 models.Book.objects.filter(comment_num__gt=F("read_num")) #为所有的书提高十块钱 models.Book.objects.all().update(price=F("price")+10)
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),
你可以使用Q 对象。
Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象
Q查询,| & ~(反)
#查询评论数大于50或者阅读数大于50的书,并且价格小于100 models.Book.objects.filter(Q(Q(comment_num__gt=50)|Q(read_num__gt=50))&Q(price__lt=100))
注意:如果出现Q 对象,它必须位于所有关键字参数的前面
错误使用方法
models.Book.objects.filter(price__lt=100,Q(comment_num__gt=10)|Q(read_num__lt=100)) #这是错误的写法,price__lt=100必须放在条件的最后面
##总结 nodels.py: class Book(models.Model): nid=models.AutoField(primary_key=True) title=models.CharField(max_length=32) # 书籍与出版社: 一对多 publisher=models.ForeignKey(to="Publish",related_name="bookList") # 书籍与作者: 多对多 authors=models.ManyToManyField("Author") class Publish(models.Model): name=models.CharField(max_length=32) class Author(models.Model): name=models.CharField(max_length=32) class AuthorDetail(models.Model): addr=models.CharField(max_length=32) author=models.OneToOneField("Author") 1、单表查询 models.Book.obejcts.all() # QuerySet [] models.Book.obejcts.filter(nid__gt=1,nid__lt=10) # QuerySet [] models.Book.obejcts.get() # model对象 models.Book.obejcts.values() # QuerySet [{},{}] models.Book.obejcts.values_list() models.Book.obejcts.exclude() models.Book.obejcts.all().first() models.Book.obejcts.all().last() models.Book.obejcts.all().orderby() models.Book.obejcts.all().reverse() models.Book.obejcts.values("price").distinct() models.Book.obejcts.all().count() models.Book.obejcts.all().exist() ---- 双下划线: models.Book.obejcts.filter(nid__gt=12) models.Book.obejcts.filter(price__in=[112,223,444]) 支持链式操作: models.Book.obejcts.all().filter().orderby("id").count() models.Book.obejcts.all().get().orderby("id").count() 1、跨表查询 ---- 基于对象 (1) 查询Linux这本书的出版社名称和作者名字 属于正向查询 按关联字段 book_obj=models.Book.obejcts.get(title="linux") book_obj.publisher.name authors_list=book_obj.authors.all() for author in authors_list: print(author.name) (2) 人民出版社出版过的所有书籍名称 属于反向查询 if 设置related_name,那么related_name的值,没有设置,按表明_set publish_obj=models.Publish.obejcts.filter(name="人民出版社").first() book_list=publish_obj.bookList.all() for book in book_list: print(book.title) (3) alex 出版社过得所有书籍的名称 属于反向查询 if 设置related_name,那么related_name的值,没有设置,按表明_set alex=models.Author.obejcts.get(name="alex") book_list=alex.book_set.all() for book in book_list: print(book.title) (4) 作者alex的所在地址 正向查询 按字段 反向查询 按表名 alex=models.Author.obejcts.get(name="alex") alex.authordetail.addr ---- 基于QuerySet 双下划线: 正向查询:按字段 反向查询:按表名 key: 1 过滤条件 2 查询结果 (1) 查询Linux这本书的出版社名称和作者名字 属于正向查询 按关联字段 models.Book.obejcts.filter(title="linux").values("publisher__name") # [{"publisher__name":"人民出版社"}] models.Book.obejcts.filter(title="linux").values("authors__name") # (2) 人民出版社出版过的所有书籍名称 models.Book.obejcts.filter(publisher__name="人民出版社").values("title") models.Publish.obejcts.filter(name="人民出版社").values("book__title") (3) alex 出版社过得所有书籍的名称 models.Book.obejcts.filter(authors__name="alex").values("title") models.Author.obejcts.filter(name="alex").values("book__title")