如何在不调用Max,Sum,Avg等聚合函数的情况下在Django中执行GROUP BY?
在我的情况下,我有一个包含{ local_path, parent, grandparent }
列的表格,我想要SELECT local_path FROM ... WHERE grandparent = "foo" GROUP BY parent
。将有多个行具有祖父母“foo”和相同的父级,但我只想要一个(任何一个)他们的local_path。
正如您所看到的,我不想取任何值的总值。而且我无法使distinct()工作,因为我想找到非独特的local_paths。
我搜索并阅读了没有任何运气的文档。谢谢!
答案 0 :(得分:2)
您可以使用order_by('parent')然后在模板中使用{%ifchanged%}来仅显示其中一个。 https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#ifchanged
答案 1 :(得分:1)
这是一个使Django在不运行聚合函数的情况下执行GROUP BY
查询的技巧。我们创建了一个自定义Func
子类,该子类被Django视为聚合函数,但实际上在SQL查询中仅求值为NULL
。
from django.db.models import Func, CharField
class NullAgg(Func):
"""Annotation that causes GROUP BY without aggregating.
A fake aggregate Func class that can be used in an annotation to cause
a query to perform a GROUP BY without also performing an aggregate
operation that would require the server to enumerate all rows in every
group.
Takes no constructor arguments and produces a value of NULL.
Example:
ContentType.objects.values('app_label').annotate(na=NullAgg())
"""
template = 'NULL'
contains_aggregate = True
window_compatible = False
arity = 0
output_field = CharField()
答案 2 :(得分:0)
如果GROUP BY parent
使用WHERE grandparent =
然后SELECT local_path
,那么SQL查询是否有效?它不应该抱怨你只允许SELECT
“分组”条款的聚合吗?
你没有说,所以我假设local_path
是一个字符串,parent
和grandparent
是ForeignKey
Model
叫Person
。
from collections import defaultdict
paths = defaultdict(list) # parent_id -> list of paths to grandpa 'foo'
for parent_id in User.objects.filter(grandparent='foo').only('parent__id'):
for path in User.objects.filter(grandparent='foo', parent__id=parent_id) \
.only('local_path'):
paths[parent__id] = path.local_path
paths
将是local_path
grandparent='foo'
值的词典