1. =========================================
    
  2. PostgreSQL specific aggregation functions
    
  3. =========================================
    
  4. 
    
  5. .. module:: django.contrib.postgres.aggregates
    
  6.    :synopsis: PostgreSQL specific aggregation functions
    
  7. 
    
  8. These functions are available from the ``django.contrib.postgres.aggregates``
    
  9. module. They are described in more detail in the `PostgreSQL docs
    
  10. <https://www.postgresql.org/docs/current/functions-aggregate.html>`_.
    
  11. 
    
  12. .. note::
    
  13. 
    
  14.     All functions come without default aliases, so you must explicitly provide
    
  15.     one. For example::
    
  16. 
    
  17.         >>> SomeModel.objects.aggregate(arr=ArrayAgg('somefield'))
    
  18.         {'arr': [0, 1, 2]}
    
  19. 
    
  20. .. admonition:: Common aggregate options
    
  21. 
    
  22.     All aggregates have the :ref:`filter <aggregate-filter>` keyword argument
    
  23.     and most also have the :ref:`default <aggregate-default>` keyword argument.
    
  24. 
    
  25. General-purpose aggregation functions
    
  26. =====================================
    
  27. 
    
  28. ``ArrayAgg``
    
  29. ------------
    
  30. 
    
  31. .. class:: ArrayAgg(expression, distinct=False, filter=None, default=None, ordering=(), **extra)
    
  32. 
    
  33.     Returns a list of values, including nulls, concatenated into an array, or
    
  34.     ``default`` if there are no values.
    
  35. 
    
  36.     .. attribute:: distinct
    
  37. 
    
  38.         An optional boolean argument that determines if array values
    
  39.         will be distinct. Defaults to ``False``.
    
  40. 
    
  41.     .. attribute:: ordering
    
  42. 
    
  43.         An optional string of a field name (with an optional ``"-"`` prefix
    
  44.         which indicates descending order) or an expression (or a tuple or list
    
  45.         of strings and/or expressions) that specifies the ordering of the
    
  46.         elements in the result list.
    
  47. 
    
  48.         Examples::
    
  49. 
    
  50.             'some_field'
    
  51.             '-some_field'
    
  52.             from django.db.models import F
    
  53.             F('some_field').desc()
    
  54. 
    
  55.     .. deprecated:: 4.0
    
  56. 
    
  57.         If there are no rows and ``default`` is not provided, ``ArrayAgg``
    
  58.         returns an empty list instead of ``None``. This behavior is deprecated
    
  59.         and will be removed in Django 5.0. If you need it, explicitly set
    
  60.         ``default`` to ``Value([])``.
    
  61. 
    
  62. ``BitAnd``
    
  63. ----------
    
  64. 
    
  65. .. class:: BitAnd(expression, filter=None, default=None, **extra)
    
  66. 
    
  67.     Returns an ``int`` of the bitwise ``AND`` of all non-null input values, or
    
  68.     ``default`` if all values are null.
    
  69. 
    
  70. ``BitOr``
    
  71. ---------
    
  72. 
    
  73. .. class:: BitOr(expression, filter=None, default=None, **extra)
    
  74. 
    
  75.     Returns an ``int`` of the bitwise ``OR`` of all non-null input values, or
    
  76.     ``default`` if all values are null.
    
  77. 
    
  78. ``BitXor``
    
  79. ----------
    
  80. 
    
  81. .. versionadded:: 4.1
    
  82. 
    
  83. .. class:: BitXor(expression, filter=None, default=None, **extra)
    
  84. 
    
  85.     Returns an ``int`` of the bitwise ``XOR`` of all non-null input values, or
    
  86.     ``default`` if all values are null. It requires PostgreSQL 14+.
    
  87. 
    
  88. ``BoolAnd``
    
  89. -----------
    
  90. 
    
  91. .. class:: BoolAnd(expression, filter=None, default=None, **extra)
    
  92. 
    
  93.     Returns ``True``, if all input values are true, ``default`` if all values
    
  94.     are null or if there are no values, otherwise ``False``.
    
  95. 
    
  96.     Usage example::
    
  97. 
    
  98.         class Comment(models.Model):
    
  99.             body = models.TextField()
    
  100.             published = models.BooleanField()
    
  101.             rank = models.IntegerField()
    
  102. 
    
  103.         >>> from django.db.models import Q
    
  104.         >>> from django.contrib.postgres.aggregates import BoolAnd
    
  105.         >>> Comment.objects.aggregate(booland=BoolAnd('published'))
    
  106.         {'booland': False}
    
  107.         >>> Comment.objects.aggregate(booland=BoolAnd(Q(rank__lt=100)))
    
  108.         {'booland': True}
    
  109. 
    
  110. ``BoolOr``
    
  111. ----------
    
  112. 
    
  113. .. class:: BoolOr(expression, filter=None, default=None, **extra)
    
  114. 
    
  115.     Returns ``True`` if at least one input value is true, ``default`` if all
    
  116.     values are null or if there are no values, otherwise ``False``.
    
  117. 
    
  118.     Usage example::
    
  119. 
    
  120.         class Comment(models.Model):
    
  121.             body = models.TextField()
    
  122.             published = models.BooleanField()
    
  123.             rank = models.IntegerField()
    
  124. 
    
  125.         >>> from django.db.models import Q
    
  126.         >>> from django.contrib.postgres.aggregates import BoolOr
    
  127.         >>> Comment.objects.aggregate(boolor=BoolOr('published'))
    
  128.         {'boolor': True}
    
  129.         >>> Comment.objects.aggregate(boolor=BoolOr(Q(rank__gt=2)))
    
  130.         {'boolor': False}
    
  131. 
    
  132. ``JSONBAgg``
    
  133. ------------
    
  134. 
    
  135. .. class:: JSONBAgg(expressions, distinct=False, filter=None, default=None, ordering=(), **extra)
    
  136. 
    
  137.     Returns the input values as a ``JSON`` array, or ``default`` if there are
    
  138.     no values. You can query the result using :lookup:`key and index lookups
    
  139.     <jsonfield.key>`.
    
  140. 
    
  141.     .. attribute:: distinct
    
  142. 
    
  143.         An optional boolean argument that determines if array values will be
    
  144.         distinct. Defaults to ``False``.
    
  145. 
    
  146.     .. attribute:: ordering
    
  147. 
    
  148.         An optional string of a field name (with an optional ``"-"`` prefix
    
  149.         which indicates descending order) or an expression (or a tuple or list
    
  150.         of strings and/or expressions) that specifies the ordering of the
    
  151.         elements in the result list.
    
  152. 
    
  153.         Examples are the same as for :attr:`ArrayAgg.ordering`.
    
  154. 
    
  155.     Usage example::
    
  156. 
    
  157.         class Room(models.Model):
    
  158.             number = models.IntegerField(unique=True)
    
  159. 
    
  160.         class HotelReservation(models.Model):
    
  161.             room = models.ForeignKey('Room', on_delete=models.CASCADE)
    
  162.             start = models.DateTimeField()
    
  163.             end = models.DateTimeField()
    
  164.             requirements = models.JSONField(blank=True, null=True)
    
  165. 
    
  166.         >>> from django.contrib.postgres.aggregates import JSONBAgg
    
  167.         >>> Room.objects.annotate(
    
  168.         ...     requirements=JSONBAgg(
    
  169.         ...         'hotelreservation__requirements',
    
  170.         ...         ordering='-hotelreservation__start',
    
  171.         ...     )
    
  172.         ... ).filter(requirements__0__sea_view=True).values('number', 'requirements')
    
  173.         <QuerySet [{'number': 102, 'requirements': [
    
  174.             {'parking': False, 'sea_view': True, 'double_bed': False},
    
  175.             {'parking': True, 'double_bed': True}
    
  176.         ]}]>
    
  177. 
    
  178.     .. deprecated:: 4.0
    
  179. 
    
  180.         If there are no rows and ``default`` is not provided, ``JSONBAgg``
    
  181.         returns an empty list instead of ``None``. This behavior is deprecated
    
  182.         and will be removed in Django 5.0. If you need it, explicitly set
    
  183.         ``default`` to ``Value('[]')``.
    
  184. 
    
  185. ``StringAgg``
    
  186. -------------
    
  187. 
    
  188. .. class:: StringAgg(expression, delimiter, distinct=False, filter=None, default=None, ordering=())
    
  189. 
    
  190.     Returns the input values concatenated into a string, separated by
    
  191.     the ``delimiter`` string, or ``default`` if there are no values.
    
  192. 
    
  193.     .. attribute:: delimiter
    
  194. 
    
  195.         Required argument. Needs to be a string.
    
  196. 
    
  197.     .. attribute:: distinct
    
  198. 
    
  199.         An optional boolean argument that determines if concatenated values
    
  200.         will be distinct. Defaults to ``False``.
    
  201. 
    
  202.     .. attribute:: ordering
    
  203. 
    
  204.         An optional string of a field name (with an optional ``"-"`` prefix
    
  205.         which indicates descending order) or an expression (or a tuple or list
    
  206.         of strings and/or expressions) that specifies the ordering of the
    
  207.         elements in the result string.
    
  208. 
    
  209.         Examples are the same as for :attr:`ArrayAgg.ordering`.
    
  210. 
    
  211.     Usage example::
    
  212. 
    
  213.         class Publication(models.Model):
    
  214.             title = models.CharField(max_length=30)
    
  215. 
    
  216.         class Article(models.Model):
    
  217.             headline = models.CharField(max_length=100)
    
  218.             publications = models.ManyToManyField(Publication)
    
  219. 
    
  220.         >>> article = Article.objects.create(headline="NASA uses Python")
    
  221.         >>> article.publications.create(title="The Python Journal")
    
  222.         <Publication: Publication object (1)>
    
  223.         >>> article.publications.create(title="Science News")
    
  224.         <Publication: Publication object (2)>
    
  225.         >>> from django.contrib.postgres.aggregates import StringAgg
    
  226.         >>> Article.objects.annotate(
    
  227.         ...     publication_names=StringAgg(
    
  228.         ...         "publications__title",
    
  229.         ...         delimiter=", ",
    
  230.         ...         ordering="publications__title",
    
  231.         ...     )
    
  232.         ... ).values("headline", "publication_names")
    
  233.         <QuerySet [{
    
  234.             'headline': 'NASA uses Python', 'publication_names': 'Science News, The Python Journal'
    
  235.         }]>
    
  236. 
    
  237.     .. deprecated:: 4.0
    
  238. 
    
  239.         If there are no rows and ``default`` is not provided, ``StringAgg``
    
  240.         returns an empty string instead of ``None``. This behavior is
    
  241.         deprecated and will be removed in Django 5.0. If you need it,
    
  242.         explicitly set ``default`` to ``Value('')``.
    
  243. 
    
  244. Aggregate functions for statistics
    
  245. ==================================
    
  246. 
    
  247. ``y`` and ``x``
    
  248. ---------------
    
  249. 
    
  250. The arguments ``y`` and ``x`` for all these functions can be the name of a
    
  251. field or an expression returning a numeric data. Both are required.
    
  252. 
    
  253. ``Corr``
    
  254. --------
    
  255. 
    
  256. .. class:: Corr(y, x, filter=None, default=None)
    
  257. 
    
  258.     Returns the correlation coefficient as a ``float``, or ``default`` if there
    
  259.     aren't any matching rows.
    
  260. 
    
  261. ``CovarPop``
    
  262. ------------
    
  263. 
    
  264. .. class:: CovarPop(y, x, sample=False, filter=None, default=None)
    
  265. 
    
  266.     Returns the population covariance as a ``float``, or ``default`` if there
    
  267.     aren't any matching rows.
    
  268. 
    
  269.     .. attribute:: sample
    
  270. 
    
  271.         Optional. By default ``CovarPop`` returns the general population
    
  272.         covariance. However, if ``sample=True``, the return value will be the
    
  273.         sample population covariance.
    
  274. 
    
  275. ``RegrAvgX``
    
  276. ------------
    
  277. 
    
  278. .. class:: RegrAvgX(y, x, filter=None, default=None)
    
  279. 
    
  280.     Returns the average of the independent variable (``sum(x)/N``) as a
    
  281.     ``float``, or ``default`` if there aren't any matching rows.
    
  282. 
    
  283. ``RegrAvgY``
    
  284. ------------
    
  285. 
    
  286. .. class:: RegrAvgY(y, x, filter=None, default=None)
    
  287. 
    
  288.     Returns the average of the dependent variable (``sum(y)/N``) as a
    
  289.     ``float``, or ``default`` if there aren't any matching rows.
    
  290. 
    
  291. ``RegrCount``
    
  292. -------------
    
  293. 
    
  294. .. class:: RegrCount(y, x, filter=None)
    
  295. 
    
  296.     Returns an ``int`` of the number of input rows in which both expressions
    
  297.     are not null.
    
  298. 
    
  299.     .. note::
    
  300. 
    
  301.         The ``default`` argument is not supported.
    
  302. 
    
  303. ``RegrIntercept``
    
  304. -----------------
    
  305. 
    
  306. .. class:: RegrIntercept(y, x, filter=None, default=None)
    
  307. 
    
  308.     Returns the y-intercept of the least-squares-fit linear equation determined
    
  309.     by the ``(x, y)`` pairs as a ``float``, or ``default`` if there aren't any
    
  310.     matching rows.
    
  311. 
    
  312. ``RegrR2``
    
  313. ----------
    
  314. 
    
  315. .. class:: RegrR2(y, x, filter=None, default=None)
    
  316. 
    
  317.     Returns the square of the correlation coefficient as a ``float``, or
    
  318.     ``default`` if there aren't any matching rows.
    
  319. 
    
  320. ``RegrSlope``
    
  321. -------------
    
  322. 
    
  323. .. class:: RegrSlope(y, x, filter=None, default=None)
    
  324. 
    
  325.     Returns the slope of the least-squares-fit linear equation determined
    
  326.     by the ``(x, y)`` pairs as a ``float``, or ``default`` if there aren't any
    
  327.     matching rows.
    
  328. 
    
  329. ``RegrSXX``
    
  330. -----------
    
  331. 
    
  332. .. class:: RegrSXX(y, x, filter=None, default=None)
    
  333. 
    
  334.     Returns ``sum(x^2) - sum(x)^2/N`` ("sum of squares" of the independent
    
  335.     variable) as a ``float``, or ``default`` if there aren't any matching rows.
    
  336. 
    
  337. ``RegrSXY``
    
  338. -----------
    
  339. 
    
  340. .. class:: RegrSXY(y, x, filter=None, default=None)
    
  341. 
    
  342.     Returns ``sum(x*y) - sum(x) * sum(y)/N`` ("sum of products" of independent
    
  343.     times dependent variable) as a ``float``, or ``default`` if there aren't
    
  344.     any matching rows.
    
  345. 
    
  346. ``RegrSYY``
    
  347. -----------
    
  348. 
    
  349. .. class:: RegrSYY(y, x, filter=None, default=None)
    
  350. 
    
  351.     Returns ``sum(y^2) - sum(y)^2/N`` ("sum of squares" of the dependent
    
  352.     variable) as a ``float``, or ``default`` if there aren't any matching rows.
    
  353. 
    
  354. Usage examples
    
  355. ==============
    
  356. 
    
  357. We will use this example table::
    
  358. 
    
  359.     | FIELD1 | FIELD2 | FIELD3 |
    
  360.     |--------|--------|--------|
    
  361.     |    foo |      1 |     13 |
    
  362.     |    bar |      2 | (null) |
    
  363.     |   test |      3 |     13 |
    
  364. 
    
  365. 
    
  366. Here's some examples of some of the general-purpose aggregation functions::
    
  367. 
    
  368.     >>> TestModel.objects.aggregate(result=StringAgg('field1', delimiter=';'))
    
  369.     {'result': 'foo;bar;test'}
    
  370.     >>> TestModel.objects.aggregate(result=ArrayAgg('field2'))
    
  371.     {'result': [1, 2, 3]}
    
  372.     >>> TestModel.objects.aggregate(result=ArrayAgg('field1'))
    
  373.     {'result': ['foo', 'bar', 'test']}
    
  374. 
    
  375. The next example shows the usage of statistical aggregate functions. The
    
  376. underlying math will be not described (you can read about this, for example, at
    
  377. `wikipedia <https://en.wikipedia.org/wiki/Regression_analysis>`_)::
    
  378. 
    
  379.     >>> TestModel.objects.aggregate(count=RegrCount(y='field3', x='field2'))
    
  380.     {'count': 2}
    
  381.     >>> TestModel.objects.aggregate(avgx=RegrAvgX(y='field3', x='field2'),
    
  382.     ...                             avgy=RegrAvgY(y='field3', x='field2'))
    
  383.     {'avgx': 2, 'avgy': 13}