ЛЕВЫЙ НАРУЖНЫЙ РЕЙТИНГ в подзапросе - PullRequest
0 голосов
/ 26 января 2019

Рассмотрим простую настройку моделей User и Content. Я хотел бы получить распределение контента по пользователям, включая 0 для пользователей без контента:

 per_user | count
----------+-------
        0 |    89
        1 |    15
        2 |    14

Ради этого вопроса можно использовать следующие модели barebone:

class User(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

class Content(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT)

Один из способов сделать это в чистом виде SQL:

SELECT
    per_user,
    count(per_user) count
FROM (
    SELECT COUNT(c.id) per_user
      FROM app_user u
      LEFT JOIN app_content c ON (c.user_id = u.id)
     GROUP BY u.id
    ) AS sub
GROUP BY
    per_user
ORDER BY
    per_user DESC;

Я могу сделать это, чтобы получить счетчик per_user:

User.objects.annotate(per_user=Count("content")).values("per_user")

К сожалению, я не могу вставить другой .annotate(c=Count("per_user")) в конце этого:

FieldError: Cannot compute Count('per_user'): 'per_user' is an aggregate
...