gpt4 book ai didi

python - 是否可以分别对多个列进行 GROUP BY 并使用 django ORM 通过其他列聚合它们中的每一个?

转载 作者:行者123 更新时间:2023-12-04 11:34:51 25 4
gpt4 key购买 nike

我知道怎么做 GROUP BY并汇总:

>>> from expenses.models import Expense
>>> from django.db.models import Sum
>>> qs = Expense.objects.order_by().values("is_fixed").annotate(is_fixed_total=Sum("price"))
>>> qs
<ExpenseQueryset [{'is_fixed': False, 'is_fixed_total': Decimal('1121.74000000000')}, {'is_fixed': True, 'is_fixed_total': Decimal('813.880000000000')}]>
但是,如果我想对其他两列做同样的事情,它只返回最后一个:
>>> qs = (
... Expense.objects.order_by()
... .values("is_fixed")
... .annotate(is_fixed_total=Sum("price"))
... .values("source")
... .annotate(source_total=Sum("price"))
... .values("category")
... .annotate(category_total=Sum("price"))
... )
>>> qs
<ExpenseQueryset [{'category': 'FOOD', 'category_total': Decimal('33.9000000000000')}, {'category': 'GIFT', 'category_total': Decimal('628')}, {'category': 'HOUSE', 'category_total': Decimal('813.880000000000')}, {'category': 'OTHER', 'category_total': Decimal('307')}, {'category': 'RECREATION', 'category_total': Decimal('100')}, {'category': 'SUPERMARKET', 'category_total': Decimal('52.8400000000000')}]>
可以只用一个查询而不是三个查询来完成我想要的吗?
预期结果:
<ExpenseQueryset [{'category': 'FOOD', 'total': Decimal('33.9000000000000')}, {... all other categories ...}, 
{'source': 'MONEY', 'total': Decimal('100')}, {... all other sources ...}, {'is_fixed': False, 'total': Decimal('1121.74000000000')}, {'is_fixed': True, 'total': Decimal('813.880000000000')}]>
最理想的情况是,它可以拆分为以下内容:
<ExpenseQueryset ['categories': [{'category': 'FOOD', 'total': Decimal('33.9000000000000')}, {... all other categories ...}], 
'sources': [{'source': 'MONEY', 'total': Decimal('100')}, {... all other sources ...}], 'type': [{'is_fixed': False, 'total': Decimal('1121.74000000000')}, {'is_fixed': True, 'total': Decimal('813.880000000000')}]]>
但这只是一个很大的好处。

最佳答案

答案是否定的,因为 SQL 是不可能的
但是您可以将以下方法与 python 编码结合使用:
我认为即使在原始 SQL 中也不可能,因为在每个查询中,您可以将一个或多个字段组合在一起,但不能将每个字段的结果分开。
但是可以通过一个查询来完成,并使用少量 Python 代码以您想要的格式合并结果 .下面我描述了如何逐步使用它。并在下一节中编写了一个 python 方法,您可以动态地将其用于任何进一步的用途。
这个怎么运作
我能提到的唯一简单的解决方案是,您按所需的 3 个字段进行分组,然后进行简单的 Python 编程以将每个字段的结果汇总在一起。
在这种方法中,你将只有 一问但每个字段分组的结果分开。

from expenses.models import Expense
from django.db.models import Sum

qs = Expense.objects.order_by().values("is_fixed", "source", "category").annotate(total=Sum("price"))
现在结果将如下所示:
<ExpenseQueryset [{'category': 'FOOD', 'is_fixed': False, 'source': 'MONEY', 'total': Decimal('33.9000000000000')}, { ...}, 
现在我们可以通过迭代这个结果来简单地聚合每个字段的结果
category_keys = []
for q in qs:
if not q['category'] in category_keys:
category_keys.append(q['category'])

# Now we have proper values of category in category_keys
category_result = []
for c in category_keys:
value = sum(item['total'] for item in qs if item['category'] == c)
category_result.append({'category': c, 'total': value)
category 的结果字段将是这样的:
[{'category': 'FOOD', 'total': 33.3}, {... other category results ...}
现在我们可以继续并按字段为其他组生成结果 is_fixedsource像下面这样:
source_keys = []
for q in qs:
if not q['source'] in source_keys:
source_keys.append(q['source'])
source_result = []
for c in source_keys:
value = sum(item['total'] for item in qs if item['source'] == c)
source_result.append({'source': c, 'total': value)

is_fixed_keys = []
for q in qs:
if not q['is_fixed'] in is_fixed_keys:
source_keys.append(q['is_fixed'])
is_fixed_result = []
for c in is_fixed_keys:
value = sum(item['total'] for item in qs if item['is_fixed'] == c)
is_fixed_result.append({'is_fixed': c, 'total': value)
全局解决方案
现在我们知道如何使用这个解决方案了,这里有一个函数,它可以给你想要的字段,并动态地为你提供正确的结果。
def find_group_by_separated_by_keys(key_list):
""" key_list in this example will be:
key_list = ['category', 'source', 'is_fixed']
"""
qs = Expense.objects.order_by().values(*tuple(key_list)).annotate(total=Sum("price"))
qs = list(qs)
result = []
for key in key_list:
key_values = []
for item in qs:
if not item[key] in key_values:
key_values.append(item[key])

key_result = []
for v in key_values:
value = sum(item['total'] for item in qs if item[key] == v)
key_result.append({key: v, 'total': value})

result.extend(key_result)
return result
现在只需在您的代码中像下面一样简单地使用它:
find_group_by_separated_by_keys(['category', 'source', 'is_fixed')
它会给出一个值列表,比如你想要的正确格式

关于python - 是否可以分别对多个列进行 GROUP BY 并使用 django ORM 通过其他列聚合它们中的每一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68749811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com