如何计算具有多个分组依据的 Django 查询集的单个字段?
How to count a single field of a django queryset with multiple group by?
假设我有一个查询集qs
。我按查询集分组如下:
(
qs.annotate(
catering_price_enabled=F("outlet__library__settings__sligro_catering_price_enabled"),
)
.values("assortment_sync_id", "catering_price_enabled")
.order_by("assortment_sync_id", "catering_price_enabled")
.distinct("assortment_sync_id", "catering_price_enabled")
)
我得到类似的东西:
<QuerySet [
{'assortment_sync_id': '01234', 'catering_price_enabled': False},
{'assortment_sync_id': '01234', 'catering_price_enabled': None},
{'assortment_sync_id': '56789', 'catering_price_enabled': None},
]>
我想做的是 annotate
这个查询集,这样我最终可以过滤值 > 1
。换句话说,每个 assortment_sync_id
只能有 catering_price_enabled
.
的值
如果我添加 .annotate(count=Count("assortment_sync_id"))
django raises NotImplementedError: annotate() + distinct(fields) is not implemented.
我尝试了这种方法,因为它显然只适用于一个字段。
如何获得下面的预期输出?
<QuerySet [
{'assortment_sync_id': '01234', 'catering_price_enabled': False, 'count': 2},
{'assortment_sync_id': '01234', 'catering_price_enabled': None, 'count': 2},
{'assortment_sync_id': '56789', 'catering_price_enabled': None, 'count': 1},
]>
“我想做的是注释这个查询集,这样我最终可以过滤值 > 1。”
如果你想得到 assortment_sync_id 大于一个的对象:
qs.annotate(
catering_price_enabled=F("outlet__library__settings__sligro_catering_price_enabled"),)
.values("assortment_sync_id", "catering_price_enabled")
.order_by("assortment_sync_id", "catering_price_enabled")
.distinct("assortment_sync_id", "catering_price_enabled")
qs.filter(assortment_sync_id__gte=1)
- 使用
.distinct()
查找具有 assortment_sync_id
和 catering_price_enabled
的不同行
- 创建一个子查询,从 1. 过滤
distinct_queryset
中的 pk
,按 assortment_sync_id
分组并计数 assortment_sync_id
- 通过在来自 1. 的不同查询集中过滤
pk
创建结果查询集,然后使用来自 2. 的计数查询集在最终结果中进行注释。
qs = qs.annotate(catering_price_enabled=F("outlet__library__settings__sligro_catering_price_enabled"))
distinct_qs = qs.distinct("assortment_sync_id", "catering_price_enabled")
count_qs = (
qs.filter(
pk__in=distinct_qs.values("pk"),
assortment_sync_id=models.OuterRef("assortment_sync_id")
)
.values("assortment_sync_id")
.order_by("assortment_sync_id")
.annotate(count=models.Count("*"))
.values("count")
)
result = (
qs.filter(pk__in=distinct_qs.values("pk"))
.annotate(
count=models.Subquery(count_qs)
).values("assortment_sync_id", "catering_price_enabled", "count")
)
假设我有一个查询集qs
。我按查询集分组如下:
(
qs.annotate(
catering_price_enabled=F("outlet__library__settings__sligro_catering_price_enabled"),
)
.values("assortment_sync_id", "catering_price_enabled")
.order_by("assortment_sync_id", "catering_price_enabled")
.distinct("assortment_sync_id", "catering_price_enabled")
)
我得到类似的东西:
<QuerySet [
{'assortment_sync_id': '01234', 'catering_price_enabled': False},
{'assortment_sync_id': '01234', 'catering_price_enabled': None},
{'assortment_sync_id': '56789', 'catering_price_enabled': None},
]>
我想做的是 annotate
这个查询集,这样我最终可以过滤值 > 1
。换句话说,每个 assortment_sync_id
只能有 catering_price_enabled
.
如果我添加 .annotate(count=Count("assortment_sync_id"))
django raises NotImplementedError: annotate() + distinct(fields) is not implemented.
我尝试了这种方法,因为它显然只适用于一个字段。
如何获得下面的预期输出?
<QuerySet [
{'assortment_sync_id': '01234', 'catering_price_enabled': False, 'count': 2},
{'assortment_sync_id': '01234', 'catering_price_enabled': None, 'count': 2},
{'assortment_sync_id': '56789', 'catering_price_enabled': None, 'count': 1},
]>
“我想做的是注释这个查询集,这样我最终可以过滤值 > 1。”
如果你想得到 assortment_sync_id 大于一个的对象:
qs.annotate(
catering_price_enabled=F("outlet__library__settings__sligro_catering_price_enabled"),)
.values("assortment_sync_id", "catering_price_enabled")
.order_by("assortment_sync_id", "catering_price_enabled")
.distinct("assortment_sync_id", "catering_price_enabled")
qs.filter(assortment_sync_id__gte=1)
- 使用
.distinct()
查找具有assortment_sync_id
和catering_price_enabled
的不同行
- 创建一个子查询,从 1. 过滤
distinct_queryset
中的pk
,按assortment_sync_id
分组并计数assortment_sync_id
- 通过在来自 1. 的不同查询集中过滤
pk
创建结果查询集,然后使用来自 2. 的计数查询集在最终结果中进行注释。
qs = qs.annotate(catering_price_enabled=F("outlet__library__settings__sligro_catering_price_enabled"))
distinct_qs = qs.distinct("assortment_sync_id", "catering_price_enabled")
count_qs = (
qs.filter(
pk__in=distinct_qs.values("pk"),
assortment_sync_id=models.OuterRef("assortment_sync_id")
)
.values("assortment_sync_id")
.order_by("assortment_sync_id")
.annotate(count=models.Count("*"))
.values("count")
)
result = (
qs.filter(pk__in=distinct_qs.values("pk"))
.annotate(
count=models.Subquery(count_qs)
).values("assortment_sync_id", "catering_price_enabled", "count")
)