我有一个模型,我想对两个值执行分组,并计算每个外部分组的每个值的百分比。
目前我只是进行查询以获取所有行并将它们放入pandas数据帧并执行类似于answer here的操作。虽然这有效但我确信如果我能让查询直接返回我需要的信息会更有效。
我目前正在使用Django 2.0.5
PostgreSQL 9.6.8
我认为窗口函数可以作为indicated here的解决方案,但我无法构建annotate
和values
的成功组合来为我提供所需的输出。
如果我能找到一种方法将摘要行作为每行的一组额外列,可以在rollup
中引入另一种可能的解决方案PostgreSQL 9.5
吗?但我也认为Django尚未支持它。
型号:
class ModelA(models.Model):
grouper1 = models.CharField()
grouper2 = models.CharField()
metric1 = models.IntegerField()
所有行:
grouper1 | grouper2 | metric1
---------+----------+---------
A | C | 2
A | C | 2
A | C | 2
A | D | 4
A | D | 4
A | D | 4
B | C | 5
B | C | 5
B | C | 5
B | D | 6
B | D | 4
B | D | 5
期望的输出:
grouper1 | grouper2 | sum(metric1) | Percentage
---------+----------+--------------+-----------
A | C | 6 | 40
A | D | 12 | 60
B | C | 15 | 50
B | D | 15 | 50
我接近我的预期
ModelA.objects.all(
).values(
'grouper1',
'grouper2'
).annotate(
SumMetric1=Window(expression=Sum('metric1'), partition_by=[F('grouper1'), F('grouper2')]),
GroupSumMetric1=Window(expression=Sum('metric1'), partition_by=[F('grouper1')])
)
但是,这会为数据库中的每个原始行返回一行,如下所示:
grouper1 | grouper2 | sum(metric1) | Percentage
---------+----------+--------------+-----------
A | C | 6 | 40
A | C | 6 | 40
A | C | 6 | 40
A | D | 12 | 60
A | D | 12 | 60
A | D | 12 | 60
B | C | 15 | 50
B | C | 15 | 50
B | C | 15 | 50
B | C | 15 | 50
B | C | 15 | 50
B | D | 15 | 50