Fonctions d’agrégation spécifiques à PostgreSQL

Ces fonctions sont disponibles dans le module django.contrib.postgres.aggregates. Elles sont décrites plus en détails dans la documentation PostgreSQL.

Note

Toutes ces fonctions n’ont pas d’alias par défaut, il faut donc en indiquer un explicitement. Par exemple :

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

Options communes d’agrégation

Tous les agrégats possèdent le paramètre mot-clé filter et doivent aussi avoir le paramètre mot-clé default.

Fonctions d’agrégation d’ordre général

ArrayAgg

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

Renvoie une liste de valeurs, y compris nulles, concaténées dans un tableau, ou default s’il n’y a aucune valeur.

distinct

Un paramètre booléen facultatif qui détermine si les valeurs de tableau seront distinctes. False par défaut.

ordering

Une chaîne facultative d’un nom de champ (précédé d’un préfixe "-" facultatif pour indiquer un ordre décroissant) ou une expression (ou un tuple/liste de chaînes ou d’expressions) qui indique le tri des éléments de la liste résultante.

Exemples :

"some_field"
"-some_field"
from django.db.models import F

F("some_field").desc()

Obsolète depuis la version 4.0: S’il n’y a aucune ligne et que default n’est pas fourni, ArrayAgg renvoie une liste vide au lieu de None. Ce comportement est obsolète et sera supprimé dans Django 5.0. Si vous en avez besoin, définissez explicitement default à Value([]).

BitAnd

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

Renvoie un entier int résultat de l’opération AND bit-à-bit de toutes les valeurs non nulles, ou default si toutes les valeurs sont nulles.

BitOr

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

Renvoie un entier int résultat de l’opération OR bit-à-bit de toutes les valeurs non nulles, ou default si toutes les valeurs sont nulles.

BitXor

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

Renvoie un entier int résultat de l’opération XOR bit-à-bit de toutes les valeurs non nulles, ou default si toutes les valeurs sont nulles. Nécessite PostgreSQL 14+.

BoolAnd

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

Renvoie True si toutes les valeurs d’entrée sont vraies, default si toutes les valeurs sont nulles ou s’il n’y a pas de valeur, sinon renvoie False.

Exemple d’utilisation :

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)

Renvoie True si au moins une valeur d’entrée est vraie, default si toutes les valeurs sont nulles ou s’il n’y a pas de valeur, sinon renvoie False.

Exemple d’utilisation :

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)

Renvoie les valeurs d’entrée sous forme de tableau JSON, ou default s’il n’y a aucune valeur. Vous pouvez interroger le résultat en utilisant les expressions de clé et d'indice.

distinct

Un paramètre booléen facultatif qui détermine si les valeurs de tableau seront distinctes. False par défaut.

ordering

Une chaîne facultative d’un nom de champ (précédé d’un préfixe "-" facultatif pour indiquer un ordre décroissant) ou une expression (ou un tuple/liste de chaînes ou d’expressions) qui indique le tri des éléments de la liste résultante.

Les exemples sont les mêmes que pour ArrayAgg.ordering.

Exemple d’utilisation :

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

Obsolète depuis la version 4.0: S’il n’y a aucune ligne et que default n’est pas fourni, JSONBAgg renvoie une liste vide au lieu de None. Ce comportement est obsolète et sera supprimé dans Django 5.0. Si vous en avez besoin, définissez explicitement default à Value('[]').

StringAgg

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

Renvoie les valeurs d’entrée concaténées dans une chaîne, séparées par la chaîne delimiter, ou default s’il n’y a aucune valeur.

delimiter

Paramètre obligatoire. Doit être une chaîne.

distinct

Un paramètre booléen facultatif qui détermine si les valeurs concaténées seront distinctes. False par défaut.

ordering

Une chaîne facultative d’un nom de champ (précédé d’un préfixe "-" facultatif pour indiquer un ordre décroissant) ou une expression (ou un tuple/liste de chaînes ou d’expressions) qui indique le tri des éléments de la chaîne résultante.

Les exemples sont les mêmes que pour ArrayAgg.ordering.

Exemple d’utilisation :

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

Obsolète depuis la version 4.0: S’il n’y a aucune ligne et que default n’est pas fourni, StringAgg renvoie une chaîne vide au lieu de None. Ce comportement est obsolète et sera supprimé dans Django 5.0. Si vous en avez besoin, définissez explicitement default à Value('').

Fonctions d’agrégation à but statistique

y et x

Les paramètres y et x de toutes ces fonctions peuvent être un nom de champ ou une expression renvoyant une donnée numérique. Les deux sont obligatoires.

Corr

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

Renvoie le coefficient de corrélation sous forme de nombre float, ou default si aucune ligne ne correspond.

CovarPop

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

Renvoie la covariance de population sous forme de nombre float, ou default si aucune ligne ne correspond.

sample

Facultatif. Par défaut, CovarPop renvoie la covariance de population générale. Cependant, si sample=True, la valeur renvoyée sera la covariance d’échantillon de population.

RegrAvgX

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

Renvoie la moyenne de la variable indépendante (sum(x)/N) sous forme de nombre float, ou default si aucune ligne ne correspond.

RegrAvgY

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

Renvoie la moyenne de la variable dépendante (sum(y)/N) sous forme de nombre float, ou default si aucune ligne ne correspond.

RegrCount

class RegrCount(y, x, filter=None)

Renvoie un entier int correspondant au nombre de lignes d’entrée dans lesquelles les deux expressions ne sont pas nulles.

Note

Le paramètre default n’est pas pris en charge.

RegrIntercept

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

Renvoie l’interception de l’axe y pour l’équation linéaire de la méthode des moindres carrés déterminée par les paires (x, y) sous forme de nombre float, ou default si aucune ligne ne correspond.

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)

Renvoie l’inclinaison pour l’équation linéaire de la méthode des moindres carrés déterminée par les paires (x, y) sous forme de nombre float, ou default si aucune ligne ne correspond.

RegrSXX

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

Renvoie sum(x^2) - sum(x)^2/N (« somme des carrés » de la variable indépendante) sous forme de nombre float, ou default si aucune ligne ne correspond.

RegrSXY

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

Renvoie sum(x*y) - sum(x) * sum(y)/N (« somme des produits » de la variable indépendante multipliée par la variable dépendante) sous forme de nombre float, ou default si aucune ligne ne correspond.

RegrSYY

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

Renvoie sum(y^2) - sum(y)^2/N (« somme des carrés » de la variable dépendante) sous forme de nombre float, ou default si aucune ligne ne correspond.

Exemples d’utilisation

Nous allons utiliser cette table d’exemple :

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

Voici quelques exemples de certaines des fonctions d’agrégation d’ordre général :

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

L’exemple suivant montre l’utilisation des fonctions d’agrégats pour les statistiques. Les mathématiques sous-jacentes ne sont pas expliquées (vous pouvez vous renseigner à ce sujet sur Wikipédia par exemple) :

>>> 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}
Back to Top