Funciones de agregado específicas de PostgreSQL

Estas funciones están disponibles desde el módulo django.contrib.postgres.aggregates. Se describen con más detalle en los docs de PostgreSQL.

Nota

Todas las funciones vienen sin alias predeterminados, por lo que debes proporcionar uno explícitamente. Por ejemplo:

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

Opciones comunes de agregado

Todos los agregados tienen el argumento de palabra clave filtro y la mayoría también tienen el argumento de palabra clave por defecto.

Funciones de agregación general-purpose

ArrayAgg

class ArrayAgg(expression, distinct=False, filter=None, default=None, order_by=(), **extra)

Devuelve una lista de valores, incluyendo nulos, concatenados en un array, o default si no hay valores.

distinct

Un argumento booleano opcional que determina si los valores del array serán distintos. Por defecto es False.

order_by

Una lista de traducciones técnicas.

Ejemplos:

from django.db.models import F

ArrayAgg("a_field", order_by="-some_field")
ArrayAgg("a_field", order_by=F("some_field").desc())

Obsoleto desde la versión 5.2: La palabra clave ordering está descontinuada. Utiliza ArrayAgg.order_by en su lugar.

BitAnd

class BitAnd(expression, filter=None, default=None, **extra)

Devuelve un int del bitwise AND de todos los valores de entrada no nulos, o default si todos los valores son nulos.

BitOr

class BitOr(expression, filter=None, default=None, **extra)

Devuelve un int del bitwise OR de todos los valores de entrada no nulos, o default si todos los valores son nulos.

BitXor

class BitXor(expression, filter=None, default=None, **extra)

Devuelve un int del bitwise XOR de todos los valores de entrada no nulos, o default si todos los valores son nulos. Requiere PostgreSQL 14+.

BoolAnd

class BoolAnd(expression, filter=None, default=None, **extra)

Devuelvo las traducciones de los textos originales manteniendo todas sus etiquetas intactas.

Ejemplo de uso:

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)

Devuelve True si al menos un valor de entrada es verdadero, default si todos los valores son nulos o si no hay valores, en otro caso False.

Ejemplo de uso:

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, order_by=(), **extra)

Devuelven los valores de entrada como una matriz JSON, o default si no hay valores. Puedes consultar el resultado utilizando búsquedas por clave e índice.

distinct

Un argumento booleano opcional que determina si los valores del array serán distintos. Por defecto es False.

order_by

Una lista de traducciones técnicas.

Los ejemplos son los mismos que para ArrayAgg.order_by.

Ejemplo de uso:

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",
...         order_by="-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}
]}]>

Obsoleto desde la versión 5.2: La palabra clave ordering está deprecada. Utiliza en su lugar JSONBAgg.order_by en su lugar.

StringAgg

class StringAgg(expression, delimiter, distinct=False, filter=None, default=None, order_by=())

Devuelven los valores de entrada concatenados como una cadena, separados por la cadena delimiter, o default si no hay valores.

delimiter

El argumento requerido. Debe ser una cadena de texto.

distinct

Un argumento booleano opcional que determina si los valores concatenados serán distintos. Por defecto, False.

order_by

Una cadena de texto (con un prefijo opcional "-" que indica orden descendente) o una expresión (o una tupla o lista de cadenas y/o expresiones) que especifica el ordenamiento de los elementos en la cadena de resultados.

Los ejemplos son los mismos que para ArrayAgg.order_by.

Ejemplo de uso:

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=", ",
...         order_by="publications__title",
...     )
... ).values("headline", "publication_names")
<QuerySet [{
    'headline': 'NASA uses Python', 'publication_names': 'Science News, The Python Journal'
}]>

Obsoleto desde la versión 5.2: La palabra clave ordering está descontinuada. Utilice StringAgg.order_by en su lugar.

Funciones de agregado para estadísticas

y y x

Los argumentos y y x para todas estas funciones pueden ser el nombre de un campo o una expresión que devuelve un dato numérico. Ambos son obligatorios.

Corr

class Corr(y, x, filter=None, default=None)

Devuelve el coeficiente de correlación como un float, o default si no hay filas coincidentes.

CovarPop

class CovarPop(y, x, sample=False, filter=None, default=None)

Regresa la covarianza poblacional como un float, o default si no hay filas que coincidan.

sample

Opcional. Por defecto, CovarPop regresa la covarianza poblacional general. Sin embargo, si sample=True, el valor de retorno será la covarianza poblacional de muestra.

RegrAvgX

class RegrAvgX(y, x, filter=None, default=None)

Regresa la media del variable independiente (sum(x)/N) como un float, o default si no hay filas que coincidan.

RegrAvgY

class RegrAvgY(y, x, filter=None, default=None)

Regresa la media de la variable dependiente (sum(y)/N) como un float, o default si no hay filas que coincidan.

RegrCount

class RegrCount(y, x, filter=None)

Regresa un int del número de filas de entrada en las que ambas expresiones no son nulas.

Nota

No se admite el argumento default.

RegrIntercept

class RegrIntercept(y, x, filter=None, default=None)

Los y-interceptos de la ecuación lineal de ajuste de mínimos cuadrados determinada por los pares (x, y) como un float, o default si no hay filas que coincidan.

RegrR2

class RegrR2(y, x, filter=None, default=None)

Devuelve el cuadrado del coeficiente de correlación como un float, o default si no hay filas que coincidan.

RegrSlope

class RegrSlope(y, x, filter=None, default=None)

Devuelve la pendiente de la ecuación lineal de ajuste de mínimos cuadrados determinada por los pares (x, y) como un float, o default si no hay filas que coincidan.

RegrSXX

class RegrSXX(y, x, filter=None, default=None)

Devuelve sum(x^2) - sum(x)^2/N («suma de cuadrados» de la variable independiente) como un float, o default si no hay filas que coincidan.

RegrSXY

class RegrSXY(y, x, filter=None, default=None)

Devuelve sum(x*y) - sum(x) * sum(y)/N («producto cruzado» de la variable independiente y dependiente) como un float, o default si no hay filas que coincidan.

RegrSYY

class RegrSYY(y, x, filter=None, default=None)

Returns sum(y^2) - sum(y)^2/N («suma de cuadrados» de la variable dependiente) como un float, o default si no hay ninguna fila que coincida.

Ejemplos de uso

Usaremos esta tabla de ejemplo:

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

Aquí tienes algunos ejemplos de funciones de agregación general-purpose:

>>> 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']}

El siguiente ejemplo muestra el uso de funciones estadísticas de agregado. La matemática subyacente no se describirá (puedes leer sobre esto, por ejemplo, en 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}