Commit 3862c568 authored by Caio Ariede's avatar Caio Ariede Committed by Tim Graham
Browse files

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

parent 4dcfbd79
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -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
====================