仅对最近添加的记录求和

时间:2010-10-07 16:16:37

标签: django django-models

我很难绕过这个Django查询。我可能用SQL来解决这个问题(也许我不得不这样做),但我想知道是否有办法用Django对象来做。

模型看起来像这样(为了清晰起见,简化了):

class Stat(model.Models):
    entry_date = models.DateTimeField()
    quantity = models.PositiveIntegerField()
    user = models.ForeignKey(User)

我需要返回用户按月分组的所有最近添加的数量的总和(使用注释和求和,我猜)。这有点难以解释,但数量不是累积的 - 我只需要处理给定用户和给定月份的最新记录,然后我需要对这些数量求和,并按月分组。如果需要更多解释,请说明。

更新:

根据要求,这是一些粗略的psudo代码。这段代码不一定是我所期望的,但它大致是我可以做的,但是以缓慢的,程序化的方式。我希望有一种方法可以通过单个查询来实现这一点,以提高速度。 (顺便说一下,这是基于Manoj Govindan的代码。)

year = list_of_months_that_have_stats
users = all_users_in_database
for months in year:
    for user in users:
        sum = Stat.object.filter(user=user, entry_date__month=month).order_by('-entry_date')[0].aggregate(sum=Sum('quantity'))
        final_output[month] = sum

另外,请注意我正在尝试获取给定月份的最后一条记录。我用order_by做这个,但据我所知这不起作用 - 这只是一个例子。

当然,上面的代码不起作用。拼图的缺失部分是降序order_by,它只获取查询中的第一项。

1 个答案:

答案 0 :(得分:1)

我不确定我到底知道你想要什么。如果我没有做对,请参阅下面的答案并纠正我。

  

我只需要处理 给定用户和给定月份 的最新记录,然后我需要对这些数量求和,并按月分组。

(强调补充)。如果这是您所需要的,那么您可以将filteraggregate结合使用,如下所示。

from django.db.models import Sum
q = Stat.objects.filter(user = user, entry_date__month = 10).aggregate(
    sum = Sum('quantity'))
print q
# {'sum': 14}

过滤条件可确保您拥有所需的user,并且month的{​​{1}}部分与您想要的月份匹配(在本例中为10月,因此entry_date )。然后,您可以10用户/月份组合的数量。

<强>更新

如果你想要每个月的用户总和(我猜这是你的意思,“按月分组”)那么你可以尝试这样的事情:

Sum

这是一个快速解释。

  1. select = dict(month = 'extract(month from entry_date)') q = Stat.objects.filter(user = user).extra( select = select).values('month').annotate( sum = Sum('quantity')) print q # [{'sum': 14, 'month': 10.0}, {'sum': 6, 'month': 9.0}] 用于指定您要从日期中提取月份部分。这是特定于数据库的。在我的例子中,语法extra特定于Postgresql。

  2. 使用extract(month from entry_date)提及您只需要values。这个很重要。如果省略month部分,则会获取所有字段,但您将无法获得所需的效果。

  3. 最后values每个记录都带有annotate。这将返回每个月的总和。