如何在不使用额外费用的情况下按月计算总数?

我目前正在使用:

  • django 1.8
  • 博士后9.3.13
  • Python 2.7

实例

enter image description here

What I have tried so far.

#Doesn't work for me but I don't mind because I don't want to use extra
truncate_month = connection.ops.date_trunc_sql('month','day')
invoices = Invoice.objects.filter(is_deleted = False,company = company).extra({'month': truncate_month}).values('month').annotate(Sum('total'))

----
#It works but I think that it's too slow if I query a big set of data
for current_month in range(1,13):
    Invoice.objects.filter(date__month = current__month).annotate(total = Sum("total"))

还有这个,答案似乎很好,但我无法导入TruncMonth模块.

Django: Group by date (day, month, year)


另外,我知道这个问题已经被问了很多次,但我没有看到任何答案.

谢谢


SOLUTION:

多亏@Vin-G的回答.

enter image description here

推荐答案

首先,您必须创建一个函数,可以为您提取月份:

from django.db import models
from django.db.models import Func

class Month(Func):
    function = 'EXTRACT'
    template = '%(function)s(MONTH from %(expressions)s)'
    output_field = models.IntegerField()

在那之后你需要做的就是

  1. 用月份注释每一行
  2. 使用values()将结果按注释月份分组
  3. 使用Sum() for each 结果加总注释

Important:如果模型类在元选项中指定了默认顺序,那么必须添加一个空order_by()子句.这是因为https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by

在 Select 输出数据时,将使用queryset的order_by()部分中提到的字段(或在模型的默认排序中使用的字段),即使values()调用中没有另外指定这些字段.这些额外字段用于将"相似"结果分组在一起,它们可以使其他相同的结果行看起来是分开的.

如果你不确定,你可以在没有任何负面影响的情况下添加空的order_by()条款.

from django.db.models import Sum

summary = (Invoice.objects
              .annotate(m=Month('date'))
              .values('m')
              .annotate(total=Sum('total'))
              .order_by())

参见此处的全部要点:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17

如果您需要更多信息:

创建自己的Func类的详细信息:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions

关于values()子句的详细信息(注意它与annotate()在子句顺序方面的交互方式):

annotate()和values()子句应用于查询的顺序很重要.如果values()子句位于annotate()之前,则将使用values()子句描述的分组来计算注释.

Postgresql相关问答推荐

将real[]数组作为完整的浮点值从postquist返回

当通过PostgreSQL FDW中的视图使用时,年龄函数的计算方式不同

无法在PostgreSQL中创建方案和表

在Haskell中定义新类型与持久化类型的惯用方法

在同一 Select 列表中两次使用jsonb_arrayElements()是否安全?

我可以将jsonb_set与来自SELECT语句的新值(第三个参数)一起使用吗?

在 postgres/presto/AWS-Athena 中,与 array_agg( (col1, col2) ) 相反的是什么来获得每组多行?

gitlab在ubuntu上安装duplicate schema问题

postgres hierarchy - 用祖先的值填充缺失值

如何使用 PostgreSQL 数据库中的函数和存储过程从动态表中获取所有数据?参数传入的表名

postgres 中的模式前缀,被调用元素的范围

如何将 NULL 值插入 UUID 而不是零

联合所有 postgresql Select 子句保留顺序

从左连接更新 Postgres

保存 geodjango PointField 时出错

为什么 rake db:migrate 有时会在 structure.sql 中添加尾随空格?

PostgreSQL 条件 where 子句

如何使用 PostgreSQL 触发器来存储更改(SQL 语句和行更改)

在 Postgres 中显示关系、序列和函数的默认访问权限

什么是 Postgres session?