Как агрегировать среднее значение расчета по двум столбцам? - PullRequest
1 голос
/ 01 апреля 2019

Я хочу написать запрос Django, чтобы получить среднее значение по всем строкам в моей таблице.Моя модель выглядит как

class StatByDow(models.Model):
    total_score = models.DecimalField(default=0, max_digits=12, decimal_places=2)
    num_articles = models.IntegerField(default=0)
    day_of_week = IntegerField(
        null=True,
        validators=[
            MaxValueValidator(6),
            MinValueValidator(0)
        ]
    )

, и я пытаюсь вычислить среднее значение, как это

everything_avg = StatByDow.objects.all().aggregate(Avg(Func(F('total_score') / F('num_articles'))))

, но это приводит к ошибке

  File "/Users/davea/Documents/workspace/mainsite_project/venv/lib/python3.7/site-packages/django/db/models/query.py", line 362, in aggregate
    raise TypeError("Complex aggregates require an alias")
TypeError: Complex aggregates require an alias

Какой правильный путьрассчитать среднее?

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Вам не нужно Func для деления, но вам нужно согласовать два разных типа полей. Используйте ExpressionWrapper вокруг Avg:

from django.db.models import ExpressionWrapper

everything_avg = (StatByDow.objects
    .aggregate(avg=ExpressionWrapper(
        Avg(F('total_score') / F('num_articles')),
        DecimalField()
    ))
)

Вы также можете использовать Cast от целого до десятичного (не с PostgreSQL, который возражает против синтаксиса Django ::numeric(NONE, NONE)) или ExpressionWrapper вокруг деления, но только один ExpressionWrapper в конце самый быстрый решение, как это происходит один раз в конце.

0 голосов
/ 01 апреля 2019

вам нужно передать имя псевдонима (очевидно, по тексту ошибки) для агрегатной функции.запрос должен быть примерно таким:

everything_avg = StatByDow.objects.all().aggregate(avg_f=Avg(Func(F('total_score') / F('num_articles'))))
...