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__)
  • 相关阅读:
    UVa 1354 天平难题 (枚举二叉树)
    广西邀请赛总结
    UVa 12118 检查员的难题 (dfs判连通, 构造欧拉通路)
    UVA
    Uva 127 "Accordian" Patience (模拟)
    UVA 10539 Almost Prime Numbers( 素数因子)
    HDU 1272 小希的迷宫(并查集)
    HDU 1213 How Many Tables (并查集)
    POJ 2236 Wireless Network(并查集)
    HDU 1233 还是畅通工程 ( Kruskal或Prim)
  • 原文地址:https://www.cnblogs.com/guojieying/p/13814870.html
Copyright © 2011-2022 走看看