在带注释和分组的Django ORM查询上聚合时发生编程错误

在带注释和分组的Django ORM查询上聚合时发生编程错误,django,django-models,django-aggregation,Django,Django Models,Django Aggregation,我正在尝试构造一个查询,以获取每个用户购买的平均、最大和最小商品数量 数据源是这个简单的销售记录表: class SalesRecord(models.Model): id = models.IntegerField(primary_key=True) user_id = models.IntegerField() product_code = models.CharField() price = models.Inte

我正在尝试构造一个查询,以获取每个用户购买的平均、最大和最小商品数量

数据源是这个简单的销售记录表:

class SalesRecord(models.Model):
    id           = models.IntegerField(primary_key=True)
    user_id      = models.IntegerField()
    product_code = models.CharField()
    price        = models.IntegerField()
    created_at   = models.DateTimeField()
对于用户购买的每个项目,都会在此表中插入一条新记录。 [注意]:用户id不是同一数据库中表的外键,因为此后端系统不管理用户信息。该值由产品的前端部分提供

以下是我构建查询的尝试:

q = SalesRecord.objects.all()
q = q.values('user_id').annotate(   # group by user and count the # of records
    count=Count('id'),              # (= # of items)
    ).order_by()
result = q.aggregate(Max('count'), Min('count'), Avg('count'))
当我尝试执行代码时,在最后一行出现编程错误:

1064,您的SQL中有一个错误 句法;检查手册 对应于您的MySQL服务器 要使用的正确语法的版本 “近”从“选择” sales_records.user_id为 用户id,统计销售记录。`' 在1号线

Django的错误屏幕显示SQL是

SELECT FROM
  (SELECT
    `sales_records`.`user_id` AS `user_id`,
    COUNT(`sales_records`.`id`) AS `count`
  FROM `sales_records`
  WHERE (`sales_records`.`created_at` >= %s AND `sales_records`.`created_at` <= %s )
  GROUP BY `sales_records`.`user_id` ORDER BY NULL) subquery
。。。结果:

{'count__max': 267, 'count__avg': 26.2563, 'count__min': 1}

按原样使用模型,不向用户发送FK,您可以获得用户id计数,然后自己进行计算:

counts = SalesRecord.objects.values('user_id').\
        annotate(count=Count('id')).values_list('count', flat=True)
(max(counts), min(counts), sum(counts) / float(len(counts)))
如果您能够将表更改为使用ForeignKey,并使您的模型看起来更像这样:

class SalesRecord(model.Models):
    user = model.ForeignKey(User)
    product_code = models.CharField()
    price        = models.IntegerField()
    created_at   = models.DateTimeField()
然后,您可以从用户对象处理问题并使用聚合:

users_with_counts = Users.objects.annotate(count=Count('salesrecord'))
stats = users_with_counts.aggregate(Max('count'), Min('count'), Avg('count'))

任何一种方法都可以通过一个数据库查询满足您的需求。

您的ORM查询确实是正确的,但缺陷在Django 1.6中。很明显,它已经在1.7中修复了。来源:

谢谢你的建议。不幸的是,它不是一个模型。当我简化模型和查询以简化问题时,名称差异逐渐显现出来。问题现根据修订后的问题进行修订。看起来你对这个问题很好奇,所以即使你现在不能修改模型,我还是选择了修改后的模型解决方案。看起来你找到了正确的代码,但是如果你在Django 1.6+上运行它,你会得到ProgrammingError:syntax error at或near FROM,就像这样:我不敢相信它仍然没有被修复。
users_with_counts = Users.objects.annotate(count=Count('salesrecord'))
stats = users_with_counts.aggregate(Max('count'), Min('count'), Avg('count'))