我正在构建一个基于django的应用程序,以收集有关特定软件用户的统计信息。
目标是显示一个图表,其中包含每月使用版本的用户数量。
这是模型:
class Installation(models.Model):
userid = models.IntegerField()
version = models.CharField(max_length=25)
timestamp = models.DateTimeField(auto_now=True)
其中timestamp
是收集有关用户数据的时间。
这是示例表的外观:
| userid | version | timestamp |
|------------------------------|
| 1 | 3.1 |<sometime> |
|------------------------------|
| 2 | 3.1 |<sometime> |
|------------------------------|
| 1 | 3.2 |<sometime> |
|------------------------------|
| 3 | 3.1 |<sometime> |
<sometime>
代表同一个月的不同时间戳。
它显示userid = 1
在同月内升级到了3.2版。
这是我的方法:
version_by_month = Installation.objects
.annotate(month=TruncMonth('timestamp'))
.values('month', 'version')
.annotate(Count('userid', distinct=True))
但是有一个问题,它将两个版本计为一个用户。例如,它对版本userid = 1
和3.1
的计数都为3.2
,并返回使用version = 3.1
为3的用户的计数,实际上应该为2。
我希望每个月都有一个输出,如果用户更改了他的版本,则仅应统计最新提交的版本。
上面显示的表的预期查询集应类似于:
[{'month': datetime.datetime(2019, 7, 1, 0, 0, tzinfo=<UTC>), 'version': 3.1, 'num': 2},
{'month': datetime.datetime(2019, 7, 1, 0, 0, tzinfo=<UTC>), 'version': 3.2, 'num': 1}]
答案 0 :(得分:0)
好吧,我注意到这已经一天多了,没有答案。虽然我不会说Django,但无法提供直接的解决方案。但是也许我可以为您指明正确的方向。
您需要通过首先消除用户的多个版本来减少计数范围。在直接sql中,这可以通过子选择来完成,该选择仅返回每个用户的最高版本,而外部选择则对结果进行计数。
-- setup
create table django_count(userid integer, version numeric, dttz timestamp with time zone);
insert into django_count(userid, version, dttz )
values (1, 3.1, now()-interval '1 month')
, (2, 3.1, now()-interval '1 month' + interval '3 days')
, (1, 3.2, now()-interval '1 month' + interval '5 days')
, (3, 3.1, now()-interval '1 month' + interval '7 days') ;
select * from django_count order by version desc;
-- count query. This is what you need in raw sql.
select version, count(*)
from (
select userid, max(version) as Version, date_trunc('month',dttz) as "For Month"
from django_count
group by userid, date_trunc('month',dttz)
) m
group by version
order by version;
如果您可以将其适应Django,我们很乐意为您提供帮助,否则,对不起,我无济于事。祝你好运。