@Alvaro가 Django의 직접 동등한 for GROUP BY
문에 대답 한 것처럼 :
SELECT actor, COUNT(*) AS total
FROM Transaction
GROUP BY actor
사용하는 것이다 values()
하고 annotate()
다음 방법 :
Transaction.objects.values('actor').annotate(total=Count('actor')).order_by()
그러나 한 가지 더 지적해야합니다.
모델에 정의 된 기본 순서가있는 경우 class Meta
의 .order_by()
절은 올바른 결과에 대한 의무입니다. 주문할 의도가없는 경우에도 건너 뛸 수 없습니다.
또한 고품질 코드의 경우 . 가없는 경우에도 항상 .order_by()
뒤에 절을 추가하는 것이 좋습니다 . 이러한 접근 방식은 진술을 미래 지향적으로 만들 것입니다 . 향후 변경 사항에 관계없이 의도 한대로 작동합니다 .annotate()
class Meta: ordering
class Meta: ordering
예를 들어 보겠습니다. 모델에 다음이있는 경우 :
class Transaction(models.Model):
actor = models.ForeignKey(User, related_name="actor")
acted = models.ForeignKey(User, related_name="acted", null=True, blank=True)
action_id = models.IntegerField()
class Meta:
ordering = ['id']
그렇다면 그러한 접근 방식은 작동하지 않을 것입니다.
Transaction.objects.values('actor').annotate(total=Count('actor'))
Django GROUP BY
는 모든 필드에서 추가 작업 을 수행하기 때문 입니다.class Meta: ordering
쿼리를 인쇄 할 경우 :
>>> print Transaction.objects.values(
SELECT "Transaction"."actor_id", COUNT("Transaction"."actor_id") AS "total"
FROM "Transaction"
GROUP BY "Transaction"."actor_id", "Transaction"."id"
집계가 의도 한대로 작동하지 않을 것이므로이 .order_by()
동작을 지우고 적절한 집계 결과를 얻으려면 절을 사용해야합니다.
참조 : 공식 Django 문서의 기본 순서 또는 order_by ()와의 상호 작용 .