Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Sum numbers and group them by the given month, is there a 'best practice'?

I don’t know what I messed up.

I tried so many methods and solutions and so far this works the best, but the ordering is messy.
I want to sum the expenses grouped by the month extracted from the datefield it was given.

So far I made this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

def index(req):
    qs = Expense.objects.filter(pom='OUT').annotate(month=TruncMonth('when')).values('month').annotate(total_amount=Sum('amount')) # pom='OUT' -- expense (there are expenses and incomes)
    return render(req, 'index.html', {'data': qs})

which works perfectly, returns them as "sept. 15.000, aug. 10.000" which is nice! But the last/latest month is always at the bottom so I wanted to give it an order_by, which returns each unique object in the model (so if sept. 15.000 came up as sept.15 10.000 and sept.22 5.000, when they’re not summed up but returned/shown separately).

What did I mess up?

EQ:
The mentioned query (without order_by) returns a queryset as of
<QuerySet [{'month': datetime.date(2022, 8, 1), 'total_amount': 15000.0}, {'month': datetime.date(2022, 9, 1), 'total_amount': 16000.0}]> by default making it look they all have been recorded at the start of the given month.

Drop a reply for further information if I forgot to include something/explained something poorly!

>Solution :

Try this:

Expense.objects.filter(pom='OUT')\
    .values('when__year', 'when__month')\
    .annotate(total_amount=Sum('amount'))\
    .order_by('-when__year','-when__month')

I included the year, otherwise it will add total_amount of next years months to this years months. Remove the - if you need an ascending order.

This will yield a result like:

<QuerySet [
    {'when__year': 2022, 'when__month':9, 'total_amount': 15000.0}, 
    {'when__year': 2022, 'when__month':8, 'total_amount': 16000.0}
]>

Edit:

Expense.objects.filter(pom='OUT')\
    .annotate(
        total_amount=Sum('amount'),
        year=models.F('when__year'),
        month=models.F('when__month')
    ).order_by('-year','-month')
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading