zoukankan      html  css  js  c++  java
  • Django——模型层之聚合查询,分组查询,F和Q查询,defer和only(查询优化)

    一、聚合查询

    ###########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查询

     # 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查询:制造  与或非的条件
    
        # 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

      # 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__)
  • 相关阅读:
    [贪心] JZOJ P3757 随机生成器
    [kmp] JZOJ P3756 动物园
    [kmp] JZOJ P3756 动物园
    [记忆化搜索] JZOJ P3767 路径
    [dfs序][线段树][并查集] JZOJ P3766 大融合
    [归并][随机算法] JZOJ P3765 想法
    [枚举][dfs] JOZJ P3749 Fox and City
    [hash] JZOJ P3669 抄卡组
    [dfs][图] 洛谷 P1330 封锁阳光大学
    [并查集]NOIP 2015 Day1 信息传递
  • 原文地址:https://www.cnblogs.com/guojieying/p/13814870.html
Copyright © 2011-2022 走看看