Подсчет уникальных значений и группировка по дате
У меня есть таблица следующего вида:
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 |
Итак, мне нужно подсчитать количество уникальных клиентов с группировкой по дате. Результат должен выглядеть так {«date»: 2024-10-10, «count_visits»: 2}.
Я попробовал несколько вариантов с annotate(unique=True) и OuterRef, но сгруппировать по дате так и не получилось.
Вот решение, работающее с диктой по следующим рекомендациям Raymond Hettinger:
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]
}
Надеюсь, это поможет вам!
Для чистого ORM-решения вы должны быть в состоянии использовать это
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))
Альтернатива решению @PTomasz для получения желаемого результата:
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))