Django聚合查询annotate、aggregate使用详情

annotate:

 多用于跨表查询,作用于queryset,其实就是给Queryset添加了一个属性,Queryset中的每个对象都会有这么一个属性,属性可以是模型中的字段,也可自定义。 

#品牌模型
class Brand(models.Model):
    name = models.CharField(max_length=20, unique=True, verbose_name='名称')
    location = models.CharField(max_length=30, default='中国', blank=True, verbose_name='品牌所属地区')
    logo = models.ImageField(null=True, blank=True, verbose_name='Logo图片')
    create_time = models.DateField(auto_now_add=True, verbose_name='创建时间')


#商品模型
class Goods(models.Model):
    name = models.CharField(max_length=50, verbose_name='名称')
    sales = models.IntegerField(default=0, null=True, blank=True, verbose_name='销量')
    comments = models.IntegerField(default=0, null=True, blank=True, verbose_name='评价数')
    brand = models.ForeignKey(Brand, null=True, on_delete=models.PROTECT, verbose_name='所属品牌')
    create_time = models.DateField(auto_now_add=True, verbose_name='创建日期')

查询每个品牌下对应的商品数量:

#查询每个品牌下的商品数量,结果为一个queryset,并且每个对象都有一个num_count属性,这个属性的值就是每个品牌下的商品数量。
result = Brand.objects.annotate(num_count=Count('goods'))  #Sun(类名小写)
result[0].num_count  #拿到queryset中第一个对象的num_count属性


#查询 华为 品牌下的商品数量,结果任然是queryset
result = Brand.objects.filter(name='华为').annotate(num_count=Count('goods'))
result[0].num_count #获取num_count属性


#与values合用,相当于按values的值进行分组聚合
result = Brand.objects.values('name').annotate(num_count=Count('goods'))
#结果:
<QuerySet [{'name': 'opoo', 'num_count': 0}, {'name': '华为', 'num_count': 3}, {'name': '小米', 'num_count': 0},  {'name': '苹果', 'num_count': 3}]>
#对应的sql:
SELECT `tb_brand`.`name`, COUNT(`tb_goods`.`id`) AS `num_count` FROM `tb_brand` LEFT OUTER JOIN `tb_goods` ON (`tb_brand`.`id` = `tb_goods`.`brand_id`) GROUP BY `tb_brand`.`name` ORDER BY NULL

result = Brand.objects.values('name', 'location').annotate(num_count=Count('goods'))#按照name和location进行分组(只有当name和location都一样时,才会被视为同一分组)
#结果:
<QuerySet [{'name': 'opoo', 'location': '中国', 'num_count': 0}, {'name': '华为', 'location': '中国', 'num_count': 3}, {'name': '小米', 'location': '中国', 'num_count': 0},  {'name': '苹果', 'location': '美国', 'num_count': 3}]>
#对应的sql:
SELECT `tb_brand`.`first_letter`, `tb_brand`.`location`, COUNT(`tb_goods`.`id`) AS `num_count` FROM `tb_brand` LEFT OUTER JOIN `tb_goods` ON (`tb_brand`.`id` = `tb_goods`.`brand_id`) GROUP BY `tb_brand`.`first_letter`, `tb_brand`.`location` ORDER BY NULL


#查询每个品牌下商品的销量
result = Brand.objects.values('name').annotate(sale_count=Sum('goods__sales')) #类名小写__字段

#添加模型之外的字段
result = Brand.objects.values('name').annotate(a_field=F('goods__sales'), b_filed=Value('default'))

aggregate:

作用于queryset,对某列进行如下操作:

  • Sum:求和
  • Count:返回数量
  • Avg:返回平均值
  • Max:求最大值
  • Min:求最小值
  • Variance:计算方差
  • StdDev:计算标准差
#对商品销量取平均值,求和
result = Goods.objects.all().aggregate(avg=Avg('sales'),sum=Sum('sales'))
#结果:
{'avg': 3.625, 'sum': 29}

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值