如何使用 Django 的查询生成器编写带有聚合字段 (Sum) 的 Case() SQL 表达式

问题描述 投票:0回答:1

我正在尝试使用 Django 的查询生成器重新创建此 SQL 语句:

CASE
  WHEN sum(imps) = 0 THEN NULL
  ELSE SUM(total_expenses) / (sum(imps) / 1000)
END as "cpm"

我已经尝试过:

MyModel.objects.annotate(
  cpm=Case(
    When(
      Sum("imps")>0,
      then=Sum("total_expenses") / Sum("imps"),
    ),
    default=0,
    output_field=FloatField(),
 )
)

但是由于这个 TypeError

'>' not supported between instances of 'Sum' and 'int'
,它不起作用。

如果有一个字段查找使我能够执行

total_imps__sum__gt=0
,我相信这会解决问题。

注:

添加

Sum("imps")
作为注释 (
total_imps=Sum("imps")
) 并执行
total_imps__gt=0
可以,但这不是理想的解决方案,因为我必须为不需要的字段创建多个注释。

python sql django django-models aggregate
1个回答
0
投票

使用

NullIf
代替

MyModel.objects.annotate( 
    Cast(
        Sum("total_expenses") /1.0/ NullIf(Sum("imps"), 0)
        output_field=FloatField()
    ),
)

您可以在原始查询中使用

alias()
来省略添加额外的注释

© www.soinside.com 2019 - 2024. All rights reserved.