Функции агрегации, специфичные для PostgreSQL

Эти функции доступны из модуля django.contrib.postgres.aggregates. Более подробно они описаны в модуле PostgreSQL docs.

Примечание

Все функции поставляются без псевдонимов по умолчанию, поэтому вы должны явно указать их. Например:

>>> SomeModel.objects.aggregate(arr=ArrayAgg('somefield'))
{'arr': [0, 1, 2]}

Общие совокупные опционы

All aggregates have the filter keyword argument and most also have the default keyword argument.

Агрегационные функции общего назначения

ArrayAgg

class ArrayAgg(expression, distinct=False, filter=None, default=None, ordering=(), **extra)[исходный код]

Returns a list of values, including nulls, concatenated into an array, or default if there are no values.

distinct

Необязательный булев аргумент, определяющий, будут ли значения массива различаться. По умолчанию имеет значение False.

ordering

Необязательная строка имени поля (с необязательным префиксом "-", который указывает порядок убывания) или выражение (или кортеж или список строк и/или выражений), которое определяет порядок элементов в списке результатов.

Примеры:

'some_field'
'-some_field'
from django.db.models import F
F('some_field').desc()

Не рекомендуется, начиная с версии 4.0: Если строк нет и default не предоставлено, ArrayAgg возвращает пустой список вместо None. Это поведение устарело и будет удалено в Django 5.0. Если вам это нужно, явно установите default в Value([]).

BitAnd

class BitAnd(expression, filter=None, default=None, **extra)[исходный код]

Returns an int of the bitwise AND of all non-null input values, or default if all values are null.

BitOr

class BitOr(expression, filter=None, default=None, **extra)[исходный код]

Returns an int of the bitwise OR of all non-null input values, or default if all values are null.

BitXor

New in Django Development version.
class BitXor(expression, filter=None, default=None, **extra)

Returns an int of the bitwise XOR of all non-null input values, or default if all values are null. It requires PostgreSQL 14+.

BoolAnd

class BoolAnd(expression, filter=None, default=None, **extra)[исходный код]

Returns True, if all input values are true, default if all values are null or if there are no values, otherwise False.

Пример использования:

class Comment(models.Model):
    body = models.TextField()
    published = models.BooleanField()
    rank = models.IntegerField()

>>> from django.db.models import Q
>>> from django.contrib.postgres.aggregates import BoolAnd
>>> Comment.objects.aggregate(booland=BoolAnd('published'))
{'booland': False}
>>> Comment.objects.aggregate(booland=BoolAnd(Q(rank__lt=100)))
{'booland': True}

BoolOr

class BoolOr(expression, filter=None, default=None, **extra)[исходный код]

Returns True if at least one input value is true, default if all values are null or if there are no values, otherwise False.

Пример использования:

class Comment(models.Model):
    body = models.TextField()
    published = models.BooleanField()
    rank = models.IntegerField()

>>> from django.db.models import Q
>>> from django.contrib.postgres.aggregates import BoolOr
>>> Comment.objects.aggregate(boolor=BoolOr('published'))
{'boolor': True}
>>> Comment.objects.aggregate(boolor=BoolOr(Q(rank__gt=2)))
{'boolor': False}

JSONBAgg

class JSONBAgg(expressions, distinct=False, filter=None, default=None, ordering=(), **extra)[исходный код]

Возвращает входные значения в виде массива JSON или default, если значений нет. Результат можно запросить с помощью key and index lookups.

distinct

Необязательный булев аргумент, определяющий, будут ли значения массива различаться. По умолчанию имеет значение False.

ordering

Необязательная строка имени поля (с необязательным префиксом "-", который указывает порядок убывания) или выражение (или кортеж или список строк и/или выражений), которое определяет порядок элементов в списке результатов.

Примеры такие же, как и для ArrayAgg.ordering.

Пример использования:

class Room(models.Model):
    number = models.IntegerField(unique=True)

class HotelReservation(models.Model):
    room = models.ForeignKey('Room', on_delete=models.CASCADE)
    start = models.DateTimeField()
    end = models.DateTimeField()
    requirements = models.JSONField(blank=True, null=True)

>>> from django.contrib.postgres.aggregates import JSONBAgg
>>> Room.objects.annotate(
...     requirements=JSONBAgg(
...         'hotelreservation__requirements',
...         ordering='-hotelreservation__start',
...     )
... ).filter(requirements__0__sea_view=True).values('number', 'requirements')
<QuerySet [{'number': 102, 'requirements': [
    {'parking': False, 'sea_view': True, 'double_bed': False},
    {'parking': True, 'double_bed': True}
]}]>

Не рекомендуется, начиная с версии 4.0: Если строк нет и default не предоставлено, JSONBAgg возвращает пустой список вместо None. Это поведение устарело и будет удалено в Django 5.0. Если вам это нужно, явно установите default в Value('[]').

StringAgg

class StringAgg(expression, delimiter, distinct=False, filter=None, default=None, ordering=())[исходный код]

Returns the input values concatenated into a string, separated by the delimiter string, or default if there are no values.

delimiter

Обязательный аргумент. Должен быть строкой.

distinct

Необязательный булев аргумент, определяющий, будут ли конкатенированные значения различаться. По умолчанию имеет значение False.

ordering

Необязательная строка имени поля (с необязательным префиксом "-", который указывает порядок убывания) или выражение (или кортеж или список строк и/или выражений), которое определяет порядок элементов в строке результата.

Примеры такие же, как и для ArrayAgg.ordering.

Пример использования:

class Publication(models.Model):
    title = models.CharField(max_length=30)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField(Publication)

>>> article = Article.objects.create(headline="NASA uses Python")
>>> article.publications.create(title="The Python Journal")
<Publication: Publication object (1)>
>>> article.publications.create(title="Science News")
<Publication: Publication object (2)>
>>> from django.contrib.postgres.aggregates import StringAgg
>>> Article.objects.annotate(
...     publication_names=StringAgg(
...         "publications__title",
...         delimiter=", ",
...         ordering="publications__title",
...     )
... ).values("headline", "publication_names")
<QuerySet [{
    'headline': 'NASA uses Python', 'publication_names': 'Science News, The Python Journal'
}]>

Не рекомендуется, начиная с версии 4.0: Если строк нет и default не предоставлено, StringAgg возвращает пустую строку вместо None. Это поведение устарело и будет удалено в Django 5.0. Если вам это нужно, явно установите default в Value('').

Агрегатные функции для статистики

y и x.

Аргументами y и x для всех этих функций могут быть имя поля или выражение, возвращающее числовые данные. Оба аргумента являются обязательными.

Corr

class Corr(y, x, filter=None, default=None)[исходный код]

Returns the correlation coefficient as a float, or default if there aren’t any matching rows.

CovarPop

class CovarPop(y, x, sample=False, filter=None, default=None)[исходный код]

Returns the population covariance as a float, or default if there aren’t any matching rows.

sample

Optional. By default CovarPop returns the general population covariance. However, if sample=True, the return value will be the sample population covariance.

RegrAvgX

class RegrAvgX(y, x, filter=None, default=None)[исходный код]

Returns the average of the independent variable (sum(x)/N) as a float, or default if there aren’t any matching rows.

RegrAvgY

class RegrAvgY(y, x, filter=None, default=None)[исходный код]

Returns the average of the dependent variable (sum(y)/N) as a float, or default if there aren’t any matching rows.

RegrCount

class RegrCount(y, x, filter=None)[исходный код]

Возвращает int количество строк ввода, в которых оба выражения не являются нулевыми.

Примечание

Аргумент default не поддерживается.

RegrIntercept

class RegrIntercept(y, x, filter=None, default=None)[исходный код]

Returns the y-intercept of the least-squares-fit linear equation determined by the (x, y) pairs as a float, or default if there aren’t any matching rows.

RegrR2

class RegrR2(y, x, filter=None, default=None)[исходный код]

Returns the square of the correlation coefficient as a float, or default if there aren’t any matching rows.

RegrSlope

class RegrSlope(y, x, filter=None, default=None)[исходный код]

Returns the slope of the least-squares-fit linear equation determined by the (x, y) pairs as a float, or default if there aren’t any matching rows.

RegrSXX

class RegrSXX(y, x, filter=None, default=None)[исходный код]

Returns sum(x^2) - sum(x)^2/N («sum of squares» of the independent variable) as a float, or default if there aren’t any matching rows.

RegrSXY

class RegrSXY(y, x, filter=None, default=None)[исходный код]

Returns sum(x*y) - sum(x) * sum(y)/N («sum of products» of independent times dependent variable) as a float, or default if there aren’t any matching rows.

RegrSYY

class RegrSYY(y, x, filter=None, default=None)[исходный код]

Returns sum(y^2) - sum(y)^2/N («sum of squares» of the dependent variable) as a float, or default if there aren’t any matching rows.

Примеры использования

Мы будем использовать этот пример таблицы:

| FIELD1 | FIELD2 | FIELD3 |
|--------|--------|--------|
|    foo |      1 |     13 |
|    bar |      2 | (null) |
|   test |      3 |     13 |

Вот примеры некоторых функций агрегирования общего назначения:

>>> TestModel.objects.aggregate(result=StringAgg('field1', delimiter=';'))
{'result': 'foo;bar;test'}
>>> TestModel.objects.aggregate(result=ArrayAgg('field2'))
{'result': [1, 2, 3]}
>>> TestModel.objects.aggregate(result=ArrayAgg('field1'))
{'result': ['foo', 'bar', 'test']}

Следующий пример демонстрирует использование статистических агрегатных функций. Математика, лежащая в основе, описываться не будет (об этом можно прочитать, например, в wikipedia):

>>> TestModel.objects.aggregate(count=RegrCount(y='field3', x='field2'))
{'count': 2}
>>> TestModel.objects.aggregate(avgx=RegrAvgX(y='field3', x='field2'),
...                             avgy=RegrAvgY(y='field3', x='field2'))
{'avgx': 2, 'avgy': 13}
Вернуться на верх