summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorCaio Ariede <caio.ariede@gmail.com>2015-08-02 14:12:13 -0300
committerTim Graham <timograham@gmail.com>2015-08-04 10:50:18 -0400
commit9f10c5cdf5dbee111556f2b800c624f0202f51e6 (patch)
treee1faa2b69b4f381e41ac48e13620aa8ef4e703f1 /docs
parent473af19273a5623202489f9daf822affcbfc0622 (diff)
[1.8.x] Fixed #25136 -- Documented Count('X', distinct=True) in aggregate topic guide.
Backport of 3862c568ac1b920188ecfbe5cd8073160206d6b9 from master
Diffstat (limited to 'docs')
-rw-r--r--docs/topics/db/aggregation.txt34
1 files changed, 28 insertions, 6 deletions
diff --git a/docs/topics/db/aggregation.txt b/docs/topics/db/aggregation.txt
index dba8aeb89a..409f58aa4c 100644
--- a/docs/topics/db/aggregation.txt
+++ b/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
====================