Как написать SQL-выражение Case() с агрегированным полем (Sum) с помощью конструктора запросов Django
Я пытаюсь воссоздать этот SQL-оператор с помощью конструктора запросов Django:
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(),
)
)
Однако это не работает из-за этой ошибки типа '>' not supported between instances of 'Sum' and 'int'
.
Если бы существовал поиск по полю, позволяющий сделать total_imps__sum__gt=0
, я уверен, что это решило бы проблему.
Примечание:
Добавление Sum("imps")
в качестве аннотации (total_imps=Sum("imps")
) и выполнение total_imps__gt=0
работает, но это не идеальное решение, поскольку мне придется создавать несколько аннотаций для полей, которые мне не понадобятся.
Используйте NullIf
вместо
MyModel.objects.annotate(
Cast(
Sum("total_expenses") /1.0/ NullIf(Sum("imps"), 0)
output_field=FloatField()
),
)
Вы можете использовать alias()
в исходном запросе, чтобы не добавлять дополнительную аннотацию