Loading docs/topics/db/aggregation.txt +28 −6 Original line number Diff line number Diff line Loading @@ -184,17 +184,39 @@ of the ``annotate()`` clause is a ``QuerySet``; this ``QuerySet`` can be modified using any other ``QuerySet`` operation, including ``filter()``, ``order_by()``, or even additional calls to ``annotate()``. Combining multiple aggregations ------------------------------- Combining multiple aggregations with ``annotate()`` will `yield the wrong results <https://code.djangoproject.com/ticket/10060>`_, as multiple tables are cross joined. Due to the use of ``LEFT OUTER JOIN``, duplicate records will be generated if some of the joined tables contain more records than the others: >>> Book.objects.first().authors.count() 2 >>> Book.objects.first().chapters.count() 3 >>> q = Book.objects.annotate(Count('authors'), Count('chapters')) >>> q[0].authors__count 6 >>> q[0].chapters__count 6 For most aggregates, there is no way to avoid this problem, however, the :class:`~django.db.models.Count` aggregate has a ``distinct`` parameter that may help: >>> q = Book.objects.annotate(Count('authors', distinct=True), Count('chapters', distinct=True)) >>> q[0].authors__count 2 >>> q[0].chapters__count 3 .. admonition:: If in doubt, inspect the SQL query! In order to understand what happens in your query, consider inspecting the ``query`` property of your ``QuerySet``. For instance, combining multiple aggregations with ``annotate()`` will yield the wrong results, as `multiple tables are cross joined`_, resulting in duplicate row aggregations. .. _multiple tables are cross joined: https://code.djangoproject.com/ticket/10060 Joins and aggregates ==================== Loading Loading
docs/topics/db/aggregation.txt +28 −6 Original line number Diff line number Diff line Loading @@ -184,17 +184,39 @@ of the ``annotate()`` clause is a ``QuerySet``; this ``QuerySet`` can be modified using any other ``QuerySet`` operation, including ``filter()``, ``order_by()``, or even additional calls to ``annotate()``. Combining multiple aggregations ------------------------------- Combining multiple aggregations with ``annotate()`` will `yield the wrong results <https://code.djangoproject.com/ticket/10060>`_, as multiple tables are cross joined. Due to the use of ``LEFT OUTER JOIN``, duplicate records will be generated if some of the joined tables contain more records than the others: >>> Book.objects.first().authors.count() 2 >>> Book.objects.first().chapters.count() 3 >>> q = Book.objects.annotate(Count('authors'), Count('chapters')) >>> q[0].authors__count 6 >>> q[0].chapters__count 6 For most aggregates, there is no way to avoid this problem, however, the :class:`~django.db.models.Count` aggregate has a ``distinct`` parameter that may help: >>> q = Book.objects.annotate(Count('authors', distinct=True), Count('chapters', distinct=True)) >>> q[0].authors__count 2 >>> q[0].chapters__count 3 .. admonition:: If in doubt, inspect the SQL query! In order to understand what happens in your query, consider inspecting the ``query`` property of your ``QuerySet``. For instance, combining multiple aggregations with ``annotate()`` will yield the wrong results, as `multiple tables are cross joined`_, resulting in duplicate row aggregations. .. _multiple tables are cross joined: https://code.djangoproject.com/ticket/10060 Joins and aggregates ==================== Loading