@@ -679,3 +679,65 @@ no books can be found:
679679Under the hood, the :ref:`default <aggregate-default>` argument is implemented
680680by wrapping the aggregate function with
681681:class:`~django.db.models.functions.Coalesce`.
682+ 
683+ .. _aggregation-mysql-only-full-group-by:
684+ 
685+ Aggregating with MySQL ``ONLY_FULL_GROUP_BY`` enabled
686+ -----------------------------------------------------
687+ 
688+ When using the ``values()`` clause to group query results for annotations in
689+ MySQL with the ``ONLY_FULL_GROUP_BY`` SQL mode enabled, you may need to apply
690+ :class:`~django.db.models.AnyValue` if the annotation includes a mix of
691+ aggregate and non-aggregate expressions.
692+ 
693+ Take the following example:
694+ 
695+ .. code-block:: pycon
696+ 
697+     >>> from django.db.models import F, Count, Greatest
698+     >>> Book.objects.values(greatest_pages=Greatest("pages", 600)).annotate(
699+     ...     num_authors=Count("authors"),
700+     ...     pages_per_author=F("greatest_pages") / F("num_authors"),
701+     ... ).aggregate(Avg("pages_per_author"))
702+ 
703+ This creates groups of books based on the SQL column ``GREATEST(pages, 600)``.
704+ One unique group consists of books with 600 pages or less, and other unique
705+ groups will consist of books with the same pages. The ``pages_per_author``
706+ annotation is composed of aggregate and non-aggregate expressions,
707+ ``num_authors`` is an aggregate expression while ``greatest_page`` isn't.
708+ 
709+ Since the grouping is based on the ``greatest_pages`` expression, MySQL may be
710+ unable to determine that ``greatest_pages`` (used in the ``pages_per_author``
711+ expression) is functionally dependent on the grouped column. As a result, it
712+ may raise an error like:
713+ 
714+ .. code-block:: pytb
715+ 
716+     OperationalError: (1055, "Expression #2 of SELECT list is not in GROUP BY
717+     clause and contains nonaggregated column 'book_book.pages' which is not
718+     functionally dependent on columns in GROUP BY clause; this is incompatible
719+     with sql_mode=only_full_group_by")
720+ 
721+ To avoid this, you can wrap the non-aggregate expression with
722+ :class:`~django.db.models.AnyValue`.
723+ 
724+ .. code-block:: pycon
725+ 
726+     >>> from django.db.models import F, Count, Greatest
727+     >>> Book.objects.values(
728+     ...     greatest_pages=Greatest("pages", 600),
729+     ... ).annotate(
730+     ...     num_authors=Count("authors"),
731+     ...     pages_per_author=AnyValue(F("greatest_pages")) / F("num_authors"),
732+     ... ).aggregate(Avg("pages_per_author"))
733+     {'pages_per_author__avg': 532.57143333}
734+ 
735+ Other supported databases do not encounter the ``OperationalError`` in the
736+ example above because they can detect the functional dependency. In general,
737+ ``AnyValue`` is useful when dealing with select list columns that involve
738+ non-aggregate functions or complex expressions not recognized by the database
739+ as functionally dependent on the columns in the grouping clause.
740+ 
741+ .. versionchanged:: 6.0
742+ 
743+     The :class:`~django.db.models.AnyValue` aggregate was added.
0 commit comments