Django-8 聚合查询与分组查询

聚合查询与分组查询

聚合查询:

aggregate(*args, **kwargs)
#1.聚合  aggregate:返回值是一个字典
    from django.db.models import Avg,Max,Min,Count
    #问题:查询所有书籍的平均价格,最高价格,最低价格

    ret = Book.objects.all().aggregate(avg_price=Avg('price'),max_price = Max('price'),min_price=Min('price'))
    print(ret)

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

1.单表分组查询 

单表查询

\

查询每个部门的的平均薪资
#************************************************聚合与分组查询*****************************************************
    #----------------------聚合  aggregate:返回值是一个字典--------------------------
    from django.db.models import Avg,Max,Min,Count

    # --------------------分组 annotate 返回的是一个queryset-----------------------------
    #查询每个部门的平均薪资

    #sql:SELECT dep AS 部门, AVG(salary) AS 平均薪资 FROM app01_emp GROUP BY dep;


    #ORM
    ret=emp1.objects.values('dep').annotate(平均薪资=Avg('salary'))
    print(ret)

 

单表分组查询语法总结:

表单模型.objects.values("group by 分组字段").annotate(聚合函数('聚合字段'))

 

  '''单表分组查询总结:

    表单模型.objects.values("group by 分组字段").annotate(聚合函数('聚合字段'))
    
    
    补充知识:
    emp1.objects.all() === select * from emp1
    emp1.objects.all().values('dep') === select emp1.dep from emp1 ===emp1.objects.values('dep')
    
    emp1.objects.all().annotate(Avg('salary'))  分组时包含了主键,这样就是去了分组的意义
    分组查询的意义在于把一个字段下多个值进行分组.如果使用了主键进行分组,相当于使用select * form emp1 没有意义
    
    '''

 2.跨表分组查询

跨表查询

#1.查询每个出版社出版的书籍数量以及出版社名称

    # SQL:SELECT  app01_publish.name AS 出版社,COUNT(nid) AS 书籍数量 FROM app01_book INNER JOIN app01_publish ON app01_book.publish_id = app01_publish.nid GROUP BY (publish_id);

    #ORM: 正向查询
    ret=Book.objects.values('publish__name').annotate(书籍数量=Count('publish__name'))
    print(ret)
    # <QuerySet [{'publish__name': '人民出版社', '书籍数量': 3}, {'publish__name': '电子工业出版社', '书籍数量': 1}, {'publish__name': '清华大学出版社', '书籍数量': 1}]>
    ''' 这里需要弄清楚sql语句的执行顺序
    注意:第一个publish__name是按照正向查询时book表下的字段publish中的name.第二个publish__name是连表时候按照表名小写加上__字段
    '''

    # 反向查询:
    ret = Publish.objects.values('nid').annotate(书籍数量=Count('book__name')).values('name','书籍数量')
    print(ret)
    # # <QuerySet [{'name': '人民出版社', '书籍数量': 3}, {'name': '电子工业出版社', '书籍数量': 1}, {'name': '清华大学出版社', '书籍数量': 1}]>
    #

 

#2.查询每个作者的名字以及出版过的书籍的最高价格
    # SQL:SELECT app01_author.`name`, MAX(price) FROM app01_author INNER JOIN app01_book_author ON app01_author.id = app01_book_author.author_id
    # 
    # INNER JOIN app01_book  ON app01_book.bid = book_id
    # 
    # GROUP BY author_id 
    ret = Author.objects.values('pk').annotate(price_max=Max('book__price')).values('name','price_max')
    print(ret)

    '''
    跨表查询总结:
    每个后表模型.objects.values('基表主键 pk').annotate(聚合函数(关联表__查询字段)).values('表模型所有字段','聚合函数字段')
例如:查询每个作者的名字以及出版过的书籍的最高价格 这里每个后面的字符,就是基表,这个基表就是作者表 '''

总结 :跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询。

 查询练习

1.统计每一个出版社的最便宜的书

   '''SQL:
    SELECT app01_publish.`name` AS Publish_name,app01_book.`name` AS Book_name,MIN(price) AS Min_price FROM app01_publish INNER JOIN app01_book
    ON app01_publish.nid = app01_book.publish_id
    GROUP BY app01_publish.nid
    '''
ORM语句:
ret = Publish.objects.values('pk').annotate(Min_price=Min('book__price')).values_list('name','Min_price') print(ret)

2.统计每本书的作者数量

  '''
    SELECT app01_book.`name`,COUNT(author_id) FROM app01_book INNER JOIN app01_book_author 
    ON app01_book.bid = app01_book_author.book_id
    GROUP BY app01_book.bid

    '''
    # ORM:
    ret = Book.objects.values('pk').annotate(c=Count('author__id')).values('name','c')
    print(ret)

3.

 

转载于:https://www.cnblogs.com/lovepy3/p/10881960.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值