首页 > 其他分享 >聚合查询、分组查询、F与Q查询

聚合查询、分组查询、F与Q查询

时间:2022-12-18 17:24:09浏览次数:44  
标签:__ 聚合 models res price 查询 objects 分组

聚合查询 aggregate( *args,**kwargs)

1.基本介绍

介绍:聚合查询通常情况下都是配合分组一起使用的. 如果你只想使用聚合函数, 但是不想分组, 那么就应该使用aggregate.

使用:直接在objects后面链接.

返回:返回字典格式的数据. 如果是对price字段求平均值, 那么返回格式是: {'price__avg': 值}

和数据库相关模块的方法:
    基本是都在django.db.models里面
       如果上述没有那么应该在django.db里面

2.五种聚合函数

  • Avg (Average) : 平均值
  • Max (Maximum) : 最大值
  • Min (Minimum) : 最小值
  • Sum (Summary) : 求和
  • Count : 个数

3.aggregate()

  • aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典
  • 键的名称是聚合值的标识符,值是计算出来的聚合值
  • 键的名称是按照字段和聚合函数的名称自动生成出来的
  • 如果你想要为聚合值指定一个名称,可以向聚合子句提供它
from django.db.models import Avg,Max,Min,Sum,Count  # 导入聚合函数

res = models.Book.objects.aggregate(Avg('price')) 
print(res)  

res = models.Book.objects.aggregate(avg_price=Avg('price'))  # 指定名称
print(res)  

res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Avg('price')) 
print(res)

分组查询 annotate

1.介绍

分组注意事项

  • 分组只能拿到分组的依据. 按照什么分组就只能拿到什么组. 其他字段不能直接获取, 需要借助一些方法(聚合函数)

  • 提示: 可以指定多个分组, 指定多个分组, 当然就可以获取多个分组之间的分组依据.

如果执行orm分组查询报错,并且有关键字sql_mode strict mode

    移除sql_mode中的only_full_group_by

步骤:

   第一步: 指定分组的依据
        第一种情况: 默认分组. annotate直接在objects后面链接时, models后面点什么就按照什么分组.
            例子: 按照书分组
            models.Book.objects.annotate(sum_price=Sum)
        第二种情况: 指定分组. annotate跟在values后面, values中指定什么字段就按照什么分组
            例子: 按照书中的价格分组. 
            models.Book.objects.values('price').annotate()
    第二步: 为分组的字段取别名
    第三步: 在annotate后面使用values可以获取分组的依据和分组之后的结果

返回:返回QuerySet对象

2.分组依据

  • values( ) 在 annotate( ) 之前则表示 group by 字段
# 默认分组依据
    如果 annotate() 直接跟在 objects 后面,则表示直接以当前的基表为分组依据
    例 : 按书来分组 : odels.Book.objects.annotate(sum_price=Sum)

# 指定分组依据
    如果 annotate() 跟在 values() 后面,则表示按照values中指定的字段来进行分组
    例 : 按照书中的price进行分组 : models.Book.objects.values('price').annotate()
  • values( ) 在 annotate( ) 之后则表示取字段
  • filter( ) 在 annotate( ) 之前则表示 where 条件
  • filter( ) 在 annotate( ) 之后则表示 having 条件

3.示例

# 分组查询
    # 统计每一本书的作者个数
    res = models.Book.objects.annotate(authors_num=Count('authors__pk')).values('title','authors_num')
    print(res)

    # 统计出每个出版社卖的最便宜的书的价格
    res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
    print(res)

    # 统计不止一个作者的图书
    # 第1步:先统计每本书的作者个数
    author_num = models.Book.objects.annotate(authors_num=Count('authors__pk'))
    # 第2步:筛选出作者个数大于1的图书
    res = models.Book.objects.annotate(author_num=Count('authors__pk')).filter(author_num__gt=1).values('title','author_num')
    print(res)

    # 查询每个作者出的书的数量和总价格
    res = models.Author.objects.annotate(total_num=Count('book__pk'),total_price=Sum('book__price'),).values('name','total_num','total_price')
    print(res)


    """按照字段分组"""
    # 统计每个出版社所出的书的数量
    res = models.Book.objects.values('publish_id').annotate(total_num=Count('pk')).values('publish__name','total_num')
    print(res)

F与Q查询

数据准备

往之前的书籍表中插入两条数据——库存量和卖出数。

第一次修改数据之后都得执行数据迁移的操作,往已有数据的表格中插入数据,执行数据迁移时无法成功,需要设置参数,不然无法添加。有两种方法:

  1. 设置默认值:default = 默认数值

  2. 允许为空:null = True

"""后续添加两个字段"""
    stock = models.IntegerField(verbose_name='库存数',default=1000)    # 设置默认值
    sold = models.IntegerField(verbose_name='卖出数',null=True)    # 允许为空

F查询介绍

  • 我们之前的例子中对一些字段的过滤和操作都是与一个常量进行比较大小, 如果我们想让字段与字段的值进行比较就无法简单实现, 于是就可以使用 F 查询了
  • 作用 : 取出某个字段对应的值

使用示例

"""
# 作用: 能够帮助你直接获取到表中某个字段对应的数据
# 使用:
    from django.db.models import F
    # 获取到某个字段对应的数据   
        F("字段__条件")
    # 查询字段对应的数据是数字类型可以直接加减运算:
        F('字段__条件') + 500
    # 字符类型需要借助Concat和Value方法
        from django.db.models.functions import Concat
        from django.db.models import Value
        Concat(F('字段__条件'), Value("str"))
        注意: 查询字段对应的数据是字符类型不能直接进行拼接. 否则操作的字段对应的所有数据将变成空白.
"""


    # 查询库存数大于卖出数的书籍
    from django.db.models import F
    res = models.Book.objects.filter(stock__gt=F('sold'))
    print(res)

    # 将所有书的价格涨80元
    models.Book.objects.update(price=F('price')+80)

    # 将所有书的名称后面都追加”爆款“两个字
    from django.db.models.functions import Concat
    from django.db.models import Value
    models.Book.objects.update(title=Concat(F('title'),Value('爆款')))

Q查询

Q查询介绍

  • filter 的字段筛选条件如果指定多个, 默认是and连接多个条件, 如果想要使用or或者not,则需要Q查询
  • 作用 : 构造 或 or与 &非 ~ 条件

示例

"""
# 作用: filter的字段筛选条件指定多个, 默认是and连接. 要实现or或者not需要借助Q查询
# 使用: 
    from django.db.models import Q
    Q(字段__条件=值)
    # 连接条件and的3种情况
        1. filter中指定多个参数逗号隔开: filter(参数1, 参数2)
        2. 查询指定多个逗号隔开: filter(Q(), Q())
        3. 使用&连接符: filter(Q() & Q())
    # 连接条件or
        filter(Q() | Q())
    # 连接条件not
        filter(~Q() | Q()) 
    # Q查询的高阶用法: 让左边指定的变量形式的查询条件可以是字符串
        q = Q()
        q.connecter = 'or'  # 指定连接符. 不指定默认and
        q.children.append(Q('字段__条件', 值))  
        res = models.XXX.objects.filter(q)
"""


from django.db.models import Q
# 1. 查询卖出数大于100 和 价格小于900的书籍 --> 连接条件 and
# res = models.Book.objects.filter(sale__gt=100, price__lt=900)
# res = models.Book.objects.filter(Q(sale__gt=100), Q(price__lt=900))
res = models.Book.objects.filter(Q(sale__gt=100) & Q(price__lt=900))
print(res)  


# 2. 查询卖出数大于100或者价格小于600的书籍 --> 连接条件 or
res = models.Book.objects.filter(Q(sale__gt=100) | Q(price__lt=600))
print(res)  


# 3. 查询卖出数不大于100或者价格小于600的书籍 --> 连接条件 not
res = models.Book.objects.filter(~Q(sale__gt=100) | Q(price__lt=600))
print(res)   


# 4. Q的高阶用法: 能够将查询条件的左边变量的形式变成字符串的形式
q = Q()               # 第一步: 实例化一个q对象
q.connector = 'or'    # 第二步: 定义连接条件
q.children.append(('sale__gt', 100))    # 第三步: 指定字符串形式的查询字段条件, 以及范围100
q.children.append(('price__lt', 600))
res = models.Book.objects.filter(q)     # 第四步: 将q对象传入filter
print(res)

 

标签:__,聚合,models,res,price,查询,objects,分组
From: https://www.cnblogs.com/chen-ao666/p/16989357.html

相关文章

  • DQL查询数据
    DQL查询数据!1.DQL(DataQueryLanguage数据查询语言)SELECT数据库中最核心的语言,最重要的语句狂神MySQL中p16school.sql文件(数据为部分数据)/*SQLyogUlti......
  • Mysql 中的升序、降序以及随机查询
    1.升序selecttime,Afromtable1orderbytimeasclimit10;+---------------------+---------+|time               |A      |+------......
  • 理解DDD中的实体、值对象、聚合根
    在领域模型映射成程序设计时,最基础的领域对象会是实体、值对象、聚合根这些。实体(Entity)通过一个唯一标识字段来区分真实世界中的每一个个体的领域对象。实体=唯一身......
  • EF Core无法翻译groupby等子查询
    烦人的表达式转化错误varquery1=emps.Grouby(v=>v.DeptId).Select(g=>new{DeptId=g.Key,Salary=g.Max(x=>x.Salary);varresult=fromdindeptsjoi......
  • Oracle-查询表大小
    --查找特定表大小setlinesize200;colownerfora18;colsegment_namefora28;selectowner,segment_name,sum(bytes/1024/1024)segment_sizefromdba_segments......
  • 聚合查询 分组查询 F与Q查询
    今日内容概要聚合查询常见的聚合函数函数关键字函数作用Max最大值Min最小值Sum求和Count统计Avg平均值用法#用之前需要导入fromdja......
  • python之路51 聚合查询 分组查询
    图书管理系统1.表设计先考虑普通字段再考虑外键字段数据库迁移、测试数据录入2.首页展示3.书籍展示4.书籍添加5.书籍编辑后端如何获取用户想要编辑的......
  • 图书管理系统、聚合查询、分组查询、F与Q查询
    图书管理系统讲解聚合查询分组查询F与Q查询图书管理系统讲解1.表设计 先考虑普通字段再考虑外键字段 数据库迁移、测试数据录入2.首页展示3.书籍展示4......
  • FAQ:说一说一条查询语句是如何执行的?
    一条SQL语句内部执行流程是怎样的?1select*fromuserwhereid=1;1.客户端发送SQL语句到服务器,先要通过连接器连接到数据库,在完成TCP握手之后,验证用户名和密码。......
  • 复赛和排名(分组排名)
     问题1:按不同科目进行排名函数公式解决:=SUM(1*IF(B$2:B$25=B2,C$2:C$25>=C2))此公式不受BC两列顺序的影响问题2:排名前30%的可以参加复赛函数公式解决:=IF(SUM(......