Group by Day in Django

Asked

Viewed 602 times

1

Does anyone there have an example of a "bat-ready" grouping by date? I tried all this here...

Subscription.objects.extra(select={'day': 'date(created_at)'}).values('day').annotate(available=Count('created_at'))

from django.db.models.aggregates import Count
Subscription.objects.extra({'date':"date(created_at)"}).values('date').annotate(count=Count('id'))



from django.db import connection
from django.db.models import Count

select = {'day': connection.ops.date_trunc_sql('day', 'created_at')}
Subscription.objects.extra(select=select).values('day').annotate(number=Count('id'))

But none returned what I want:

2016-01-22, 10
2016-01-21, 5
2016-01-15, 7

2 answers

1

*To group per day, simply group by date.

Being of the type DateField, just do it this way:

>>> from django.db.models import Count
>>> Subscription.objects.values('created_at').annotate(number=Count('id'))
[{'number': 1, 'created_at': datetime.date(2015, 12, 5)}]

If the guy is DateTimeField, I converted to the type DateField using conditionals and functions:

>>> from django.db.models import DateField, Case, F
>>> Subscription.objects.annotate(tipo_datefield=Case(default=F('created_at'), output_field=DateField())).values('tipo_datefield').annotate(number=Count('id'))

Another way to accomplish this (not yet in the documentation) is by using Date to extract the day:

from django.db.models.expressions import Date
Subscription.objects.annotate(
    day=Date('created_at', 'day')
).values('day').annotate(number=Count('id'))
  • It’s like Datetimefield and it’s counting one by one, it’s not grouping. I said I need to group by day?

  • @Regisdasilva if the guy is datefield it will group by day, need not extract the day of the date. I added a way to group by date if it is a datetime.

  • it is not grouping by day, it is returning number=1 for each date, but it was to return day 22, 3; 21, 10 for example.

  • @Regisdasilva here is working

  • @Regisdasilva added another solution.

  • Strange, none of the solutions worked. Ah, check my github https://github.com/rg3915/wttd2/blob/master/eventex/subscriptions/models.py#L11 that the field is Datetimefield. I’m wearing Django 1.9.1

  • @Regisdasilva the problem is not in the code, maybe you have not registered anything, or there are no registrations on the same day, what I put is all correct and working 100%.

  • @Regisdasilva what error is appearing?

Show 4 more comments

0


Django Aggregation, group by day

import datetime
import itertools
qs = Subscription.objects.values('created_at').values('created_at')
grouped = itertools.groupby(qs, lambda d: d.get('created_at').strftime('%Y-%m-%d'))
[(day, len(list(this_day))) for day, this_day in grouped]

Return

[('2016-01-24', 7),
 ('2016-01-22', 13),
 ('2016-01-21', 5),
 ('2016-01-15', 9),
 ('2016-01-14', 1),
 ('2016-01-09', 20)]

http://chase-seibert.github.io/blog/2012/02/24/django-aggregation-group-by-day.html

  • @Orion Thank you for your help.

  • Note that this response does the grouping in the application (python) instead of in the BD (SQL), and so can be much less efficient in the case of a large dataset (because all the rows have to be returned from the BD even if only its aggregation is required).

  • @mgibsonbr and what you recommend?

  • If the Orion solution did not work for you, then unfortunately I have nothing better to recommend... You could use SQL "raw" using extra, but it’s also not ideal (because it reduces the portability of the code). Anyway, I’m not saying that the technique of this answer is bad, I’m just pointing out a performance feature of it - which becomes more relevant as the volume of data increases (but which may still be satisfactory, it is you who have to evaluate according to your particular case).

  • @mgibsonbr OK, thanks for the comments, but for now is already solved with the solution I posted above. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.