###########1 聚合查询(聚合函数:最大,最小,和,平均,总个数) from django.db.models import Avg,Max,Min,Count,Sum #1 计算所有图书的平均价格 # aggregate结束,已经不是queryset对象了 # book=models.Book.objects.all().aggregate(Avg('price')) # 起别名 # book=models.Book.objects.all().aggregate(avg=Avg('price')) #2 计算总图书数 # book = models.Book.objects.all().aggregate(count=Count('id')) # 3 计算最低价格的图书 # book = models.Book.objects.all().aggregate(min=Min('price')) # 4 计算最大价格图书 # book = models.Book.objects.all().aggregate(max=Max('price')) # print(book)
ps:
多表本质也是单表
建议用 主键group by
尽量以分组的那个表为基表
####2 分组查询 ''' 查询每一个部门名称以及对应的员工数 比如类似表: book: id name price publish 1 金品 11.2 1 2 西游 14.2 2 3 东游 16.2 2 4 北邮 19.2 3 ''' # 示例一:查询每一个出版社id,以及出书平均价格 # select publish_id,avg(price) from app01_book group by publish_id; # annotate # annotate() 内写聚合函数 # values在前表示group by的字段 # values在后表示取某几个字段 # filter在前表示where # filter在后表示having # from django.db.models import Avg, Count, Max, Min # ret=models.Book.objects.values('publish_id').annotate(avg=Avg('price')).values('publish_id','avg') # print(ret) # 查询出版社id大于1的出版社id,以及出书平均价格 #select publish_id,avg(price) from app01_book where publish_id>1 group by publish_id; # ret=models.Book.objects.values('publish_id').filter(publish_id__gt=1).annotate(avg=Avg('price')).values('publish_id','avg') # print(ret) # 查询出版社id大于1的出版社id,以及出书平均价格大于30的 # select publish_id,avg(price)as aaa from app01_book where publish_id>1 group by publish_id HAVING aaa>30; # ret = models.Book.objects.values('publish_id').filter(publish_id__gt=1).annotate(avg=Avg('price')).filter(avg__gt=30).values( # 'publish_id', 'avg') # print(ret) ## 查询每一个出版社出版的书籍个数 # pk 代指主键 # ret=models.Book.objects.get(pk=1) # print(ret.name) # ret=models.Publish.objects.values('pk').annotate(count=Count('book__id')).values('name','count') # print(ret) # 如果没有指定group by的字段,默认就用基表(Publish)主键字段作为group by的字段 # ret=models.Publish.objects.annotate(count=Count('book__id')).values('name','count') # print(ret) # 另一种方式实现 # ret=models.Book.objects.values('publish').annotate(count=Count('id')).values('publish__name','count') # print(ret) #查询每个作者的名字,以及出版过书籍的最高价格(建议使用分组的表作为基表) # 如果不用分组的表作为基表,数据不完整可能会出现问题 # ret=models.Author.objects.values('pk').annotate(max=Max('book__price')).values('name','max') # ret = models.Author.objects.annotate(max=Max('book__price')).values('name', 'max') # ret= models.Book.objects.values('authors__id').annotate(max=Max('price')).values('authors__name','max') # print(ret) #查询每一个书籍的名称,以及对应的作者个数 # ret=models.Book.objects.values('pk').annotate(count=Count('authors__id')).values('name','count') # ret=models.Book.objects.annotate(count=Count('authors__id')).values('name','count') # ret=models.Author.objects.values('book__id').annotate(count=Count('id')).values('book__name','count') # # print(ret) #统计不止一个作者的图书 # ret=models.Book.objects.values('pk').annotate(count=Count('authors__id')).filter(count__gt=1).values('name','count') # ret = models.Author.objects.values('book__id').annotate(count=Count('id')).filter(count__gt=1).values('book__name', 'count') # print(ret) # 统计价格数大于10元,作者的图书 ret = models.Book.objects.values('pk').filter(price__gt=10).annotate(count=Count('authors__id')).values('name', 'count') print(ret) #统计价格数大于10元,作者个数大于1的图书 ret = models.Book.objects.values('pk').filter(price__gt=10).annotate(count=Count('authors__id')).filter(count__gt=1).values('name', 'count') print(ret)
# F查询:取出数据库的某个字段的值 # 把read_num都加1 from django.db.models import F ret=models.Book.objects.all().update(read_num=F('read_num')+1) print(ret) #查询评论数大于阅读数的书籍 ret=models.Book.objects.all().filter(commit_num__gt=F('read_num')) for i in ret: print(i.name) ## 查询评论数大于阅读数2倍的书籍 ret=models.Book.objects.filter(commit_num__gt=F('read_num')*2) print(ret)
# Q查询:制造 与或非的条件 # Q查询:制造 与或非的条件 # 查询名字叫egon或者价格大于100的书 from django.db.models import Q # ret=models.Book.objects.filter(Q(name='egon') | Q(price__gt=100)) # 查询名字叫egon并且价格大于100的书 # ret=models.Book.objects.filter(Q(name='egon') & Q(price__gt=100)) # ret=models.Book.objects.filter(name='egon',price__gt=100) # 查询名字不为egon的书 # ret = models.Book.objects.filter(~Q(name='egon')) # print(ret) # Q可以嵌套 ret = models.Book.objects.filter((Q(name='egon') & Q(price__lt=100)) | Q(id__lt=3)) print(ret)
# defer和only(查询优化相关) # only保持是book对象,但是只能使用only指定的字段 # books = models.Book.objects.all().only('name') # print(books[0].name) # print(books[0].price) # 能出来, # books = models.Book.objects.all().only('name') # # print(books[0].__dict__) books = models.Book.objects.all().defer('name','price') print(books[0].__dict__)