Pk 字段总是以结果查询 GROUP BY 子句结束

Posted

技术标签:

【中文标题】Pk 字段总是以结果查询 GROUP BY 子句结束【英文标题】:Pk fields always ends up in resulting query GROUP BY clause 【发布时间】:2016-08-15 11:09:36 【问题描述】:

我的模型层次结构定义如下:

class Meal(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    discount_price = models.DecimalField(blank=False, null=False, decimal_places=2, max_digits=4)
    normal_price = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=4)
    available_count = models.IntegerField(blank=False, null=False)
    name = models.CharField(blank=False, null=False, max_length=255)
    active = models.BooleanField(blank=False, null=False, default=True)

class Order(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    number = models.CharField(max_length=64, blank=True, null=True)
    buyer_phone = models.CharField(max_length=32, blank=False, null=False)
    buyer_email = models.CharField(max_length=64, blank=False, null=False)
    pickup_time = models.DateTimeField(blank=False, null=False)
    taken = models.BooleanField(blank=False, null=False, default=False)

class OrderItem(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items')
    meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
    amount = models.IntegerField(blank=False, null=False, default=1)

我正在尝试获取有关订单的一些统计信息,我想出了如下所示的 django orm 调用:

queryset.filter(created_at__range=[date_start, date_end])\
        .annotate(price=Sum(F('items__meal__discount_price') * F('items__amount'), output_field=DecimalField()))
        .annotate(created_at_date=TruncDate('created_at'))\
        .annotate(amount=Sum('items__amount'))\
        .values('created_at_date', 'price', 'amount')

然而,上面的内容并没有给我预期的结果,因为由于某种原因,id 列仍然会出现在 sql 查询的 GROUP BY 子句中。有什么帮助吗?

【问题讨论】:

【参考方案1】:

为了让它发挥作用,我必须做到以下几点:

qs.filter(created_at__range=[date_start, date_end])\
  .annotate(created_at_date=TruncDate('created_at'))\
  .values('created_at_date')\
  .annotate(price=Sum(F('items__meal__discount_price') * F('items__amount'), 
                        output_field=DecimalField()))
  .annotate(amount=Sum('items__amount'))

哪种有意义 - 我只提取 created_at 字段,对其进行转换,然后用其他两个字段注释结果。

【讨论】:

以上是关于Pk 字段总是以结果查询 GROUP BY 子句结束的主要内容,如果未能解决你的问题,请参考以下文章

mysql group by 的用法,集合后取出指定的字段

having和group by的区别?

GROUP BY 子句必须与聚合函数一起使用?

使用Group By注意事项

选择的字段不包含在 GROUP BY 子句中,那么这个 Access 查询如何成功运行?

SQL 查询,特定字段上的一条记录,带有 group by 子句