Browse Source

Fixed #25136 -- Documented Count('X', distinct=True) in aggregate topic guide.

Caio Ariede 9 years ago
parent
commit
3862c568ac
1 changed files with 28 additions and 6 deletions
  1. 28 6
      docs/topics/db/aggregation.txt

+ 28 - 6
docs/topics/db/aggregation.txt

@@ -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
 ====================