[Question] Django 2 - how to sum values based on filter and group by Year-Month

249 views
Skip to first unread message

Charles Sartori

unread,
Jul 26, 2018, 10:25:57 PM7/26/18
to Django users
I have the following table:

2018-01-01      10
2018-01-15      20
2018-01-31      30
2018-02-01      10
2018-03-01      10
2018-03-20      20

I need to Sum() the values filtering it with 
1 - sum(values) where date < first day of the month
2 - sum(values) where date < last day of the month

Expected result(something like that):
[
 {'year-month': '2018-01'}, {'sum_before_month_day_one': 0}, {'sum_before_last_month_day': 60},
 {'year-month': '2018-02'}, {'sum_before_month_day_one': 60}, {'sum_before_last_month_day': 70},
 {'year-month': '2018-03'}, {'sum_before_month_day_one': 70}, {'sum_before_last_month_day': 100},
]

So far I manage to sum values and group by month:

In [12]: result = Sale.objects \
    ...:     .annotate(date=TruncMonth('event_date')) \
    ...:     .values('date') \
    ...:     .annotate(quantity=Sum('quantity')) \
    ...:     .values('date', 'quantity') \
    ...:     .order_by('date')

In [13]: for i in result: print(i)

{'date': datetime.date(2018, 1, 1), 'quantity': 60.0}
{'date': datetime.date(2018, 2, 1), 'quantity': 10.0}
{'date': datetime.date(2018, 3, 1), 'quantity': 30.0}

Gerald Brown

unread,
Jul 27, 2018, 2:13:50 AM7/27/18
to django...@googlegroups.com

I am having a similar problem where I want to get the total (SUM) of about 20 - 30 items in a current day.  I can get the list of customers names and payments in a html table but so far haven't been able to get the SUM of those payments.  I have tried using Django ORM AGGREGATE SUM('integer field') but I am not able to get the results. 

I haven't tried grouping yet in my project but will probably have to in the near future.  I think it is possible to group by week & month and then get a sum of those groups.  MariaDB has a function "MONTH" and " WEEKOFYEAR" which I hope will help with the grouping.  One problem that I have is that in my customer table I have a ForeignKey link to a Payment_amount table so the user can look up the payment amount instead of typing it in where an extra/less zero could be entered.

One web site that might offer some suggestions on solving your/my problem is: https://simpleisbetterthancomplex.com/tutorial/2016/12/06/how-to-create-group-by-queries.html.  This site has a lot of posts relating to Django.

Good luck & I would be interested in how you solved this problem.

Gerald S. Brown
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/a57a7058-ea08-4909-8e98-c678aa9969cc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Melvyn Sopacua

unread,
Jul 27, 2018, 6:20:18 AM7/27/18
to django...@googlegroups.com
On vrijdag 27 juli 2018 04:25:56 CEST Charles Sartori wrote:

> I need to Sum() the values filtering it with
> 1 - sum(values) where date < first day of the month
> 2 - sum(values) where date < last day of the month
>
> Expected result(something like that):
> [
> {'year-month': '2018-01'}, {'sum_before_month_day_one': *0*},
> {'sum_before_last_month_day': *60*},
> {'year-month': '2018-02'}, {'sum_before_month_day_one': *60*},
> {'sum_before_last_month_day': *70*},
> {'year-month': '2018-03'}, {'sum_before_month_day_one': *70*},
> {'sum_before_last_month_day': *100*},
> ]

Break it down:
- the only relevant part is the sum of the month
- the other is a running total you can keep track of without putting the
burdon on the database

But, requirement 2) applied to the first result should strictly yield 30, not
60. But I think that's an error in your requirement description.

> {'date': datetime.date(2018, 1, 1), 'quantity': 60.0}

(30 is *at* the last day of the month, not before it)
> 2018-01-31 30

--
Melvyn Sopacua


Reply all
Reply to author
Forward
0 new messages