PostgreSQL 特有聚合函数

这些功能可以从 django.contrib.postgres.aggregates 模块中获得。在 PostgreSQL docs 中对这些功能有更详细的描述。

备注

All functions come without default aliases, so you must explicitly provide one. For example:

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

通用聚合选项

所有的聚合都有 filter 关键字参数,大多数也有 default 关键字参数。

通用聚合函数

ArrayAgg

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

返回一个值的列表,包括空值,串联成一个数组,如果没有值,则返回 default

distinct

一个可选的布尔参数,用于确定数组值是否会被去重。默认值为 False

ordering

可选的字段名字符串(可选的 "-" 前缀表示降序)或表达式(或字符串和/或表达式的元组或列表),指定结果列表中元素的顺序。

举例:

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

F("some_field").desc()
Changed in Django 5.0:

In older versions, if there are no rows and default is not provided, ArrayAgg returned an empty list instead of None. If you need it, explicitly set default to Value([]).

BitAnd

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

返回所有非空输入值的位式 ANDint,如果所有值为空,则返回 default

BitOr

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

返回所有非空输入值的位式 ORint,如果所有值为空,则返回 default

BitXor

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)

如果所有输入值为真,返回 True,如果所有值为空或没有值,返回 default,否则返回 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)

如果至少有一个输入值为真,则返回 True,如果所有值都为空或没有值,则返回 default,否则返回 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 index 查找 来查询结果。

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}
]}]>
Changed in Django 5.0:

In older versions, if there are no rows and default is not provided, JSONBAgg returned an empty list instead of None. If you need it, explicitly set default to Value([]).

StringAgg

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

返回输入值串联成的字符串,用 delimiter 字符串分隔,如果没有值,则返回 default

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'
}]>
Changed in Django 5.0:

In older versions, if there are no rows and default is not provided, StringAgg returned an empty string instead of None. If you need it, explicitly set default to Value("").

统计的聚合功能

yx

所有这些函数的参数 yx 可以是字段名或返回数值数据的表达式。这两个参数都是必须的。

Corr

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

返回相关系数为 float,如果没有任何匹配行,则返回 default

CovarPop

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

返回人口协方差为 float,如果没有任何匹配的行,则返回 default

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)

返回自变量的平均数(sum(x)/N)为 float,如果没有任何匹配的行,则返回 default

RegrAvgY

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

返回因变量的平均数(sum(y)/N)为 float,如果没有匹配的行,则为 default

RegrCount

class RegrCount(y, x, filter=None)

返回两个表达式都不为空的输入行数的 int

备注

不支持 default 参数。

RegrIntercept

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

返回由 (x, y) 对确定的最小二乘法线性方程的 y 截距为 float,如果没有任何匹配行,则返回 default

RegrR2

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

返回相关系数的平方为 float,如果没有任何匹配行,则返回 default

RegrSlope

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

返回由 (x, y) 对确定的最小二乘法线性方程的斜率为 float,如果没有任何匹配行,则返回 default

RegrSXX

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

返回 sum(x^2) - sum(x)^2/N``(自变量的 “平方之和”)为 ``float,如果没有任何匹配的行,则返回 default

RegrSXY

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

返回 sum(x*y) - sum(x) * sum(y)/N``(自变量与因变量的“乘积之和”)为 ``float,如果没有任何匹配的行,则返回 default

RegrSYY

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

返回 sum(y^2) - sum(y)^2/N``(因变量的“平方之和”)为 ``float,如果没有任何匹配行,则返回 default

使用实例:

We will use this example table:

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

Here's some examples of some of the general-purpose aggregation functions:

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

The next example shows the usage of statistical aggregate functions. The underlying math will be not described (you can read about this, for example, at 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}