我有以下模型:
class Visit(models.Model):
...
device_id = models.CharField(...)
created_at = models.DateTimeField(auto_now_add=True)
...
此模型基本上表示对一个地方的访问,device_id唯一地标识一个人,并且同一个人可以多次访问该地方,因此在此表中创建了多个实体。
我正在此模型之上构建分析方法。我想做的一件事是,在过去30天中,显示当天仅拜访过一次的人数。通过一种基本方法,我可以每天这样发出数据库查询:
for date in dates:
start_time = date
end_time = date + datetime.timedelta(days=1)
Visitor.objects.filter(
site__in=node_descendants,
created_at__gte=start_date,
created_at__lt=end_date)
).values('device_id').annotate(visit_count=Count('device_id')).filter(visit_count=1).count()
现在,我想使用像这样的子查询通过一个查询来计算30天范围内每一天的数据:
single_visitor_query = Visitor.objects.filter(
created_at__date=OuterRef('truncated_date')
).order_by().values('device_id')
.annotate(visit_count=Count('device_id')).filter(visit_count=1)
.annotate(count=Count('*')).values('count')
chart_data_query = Visitor.objects.filter(
created_at__gte=start_date, # Start of month
created_at__lt=end_date, # End of month
).annotate(
truncated_date=TruncDay('created_at')
).values('truncated_date').distinct().annotate(
single_visitor_count=Subquery(single_visitor_query[:1], output_field=PositiveIntegerField()
)
这种方法有很多问题: