Count unique values and group by date

I have a table like:

client_id action date (datetime)
1 visit 2024-10-10 10:00
1 visit 2024-10-10 12:00
1 visit 2024-10-10 13:00
2 visit 2024-10-10 13:00

So, I need to count amount of unique clients with group by date. The result should look like {'date': 2024-10-10, "count_visits": 2}.

I tried several variations with annotate(unique=True) and OuterRef, but it never worked to group by date.

here is a solution working with dict following Raymond Hettinger precomandations:

from collections import defaultdict

# get the first queryset:
temp_qs = MyModel.objects.filter(
    action="visits",
    date__gte=from_date,
    date__gte=to_date,
)

# get a dict with visits for each client:
visits_dict= defaultdict(list)
for temp_val in temp_qs:
visits_dict[temp_val.client].append(temp_val)

# count what you except:
count_dict = {client : defaultdict(int) for client in visits_dict}
count_dict=defaultdict(int)
for client,visits in visits_dict.items():
    count_dict[client][visits.date]+=1

# if you really want a dict as you wrote :
your_dict = dict()
for client, date in count_dict.items():
    your_dict[client]= {
        'date': date, 
        "count_visits": count_dict[client][date]
    }

I hope it will help you !

For pure ORM solution you should be able to use this

from django.db.models import Count
from django.db.models.functions import TruncDate

YourTable.objects.annotate(pure_date=TruncDate('your_date_field_name')).values('pure_date').annotate(count_visits=Count('client_id', distinct=True))

An alternative to @PTomasz solution in order to obtain the desired result:

from django.db.models import Count, Value, CharField
from django.db.models.functions import Concat

YourModel.objects.values(
    timestamp=Concat(
        "date__year",
        Value("-"),
        "date__month",
        Value("-"),
        "date__day",
        output_field=CharField(),
    )
).annotate(count_visits=Count("client_id", distinct=True))
Back to Top