Я пытаюсь воссоздать этот оператор 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(),
)
)
Однако это не работает из-за ошибки TypeError '>' not supported between instances of 'Sum' and 'int'
.
Если бы был поиск по полю, который позволил бы мне сделать total_imps__sum__gt=0
, я уверен, что это решило бы проблему.
Добавление Sum("imps")
в качестве аннотации (total_imps=Sum("imps")
) и выполнение total_imps__gt=0
работает, но это не идеальное решение, поскольку мне придется создавать несколько аннотаций для полей, которые мне не понадобятся.
На самом деле это выражение является частью более крупного выражения SQL, которое мы хотим сделать динамическим и добавить к нему фильтры. Вот почему мы проводим его рефакторинг, чтобы использовать построитель запросов.
Это понятно, но это вовсе не повод использовать построитель запросов.
Зачем запутывать красивое и чистое выражение SQL магическими заклинаниями и заклинаниями построителя запросов? Используйте собственный SQL.