简体   繁体   English

如何在 Django 查询集中对条件求和

[英]How to sum with condition in a Django queryset

I am trying to sum Django query with a condition.我正在尝试将 Django 查询与条件相加。 Suppose I have got some data like this:假设我有一些这样的数据:

| Name | Type |
---------------
| a    | x    |
| b    | z    |
| c    | x    |
| d    | x    |
| e    | y    |
| f    | x    |
| g    | x    |
| h    | y    |
| i    | x    |
| j    | x    |
| k    | x    |
| l    | x    |

And these types are string and they have values, like x = 1, y = 25, z = -3这些类型是字符串,它们有值,比如x = 1, y = 25, z = -3

How can I sum up all the values without a loop?如何在没有循环的情况下总结所有值? Currently using a loop.目前使用循环。

data = A.objects.all()
sum = 0
mapp = {'x': 1, 'y': 25, 'z': -3}
for datum in list(data):
    sum = sum + mapp[datum.type]
print(sum)

To perform the calculation inside the database use Queryset.aggregate() with an aggregate expression that uses Case / When :要在数据库中执行计算,请使用Queryset.aggregate()和使用Case / When聚合表达式

from django.db.models import Sum, Case, When

A.objects.all().aggregate(
    amount=Sum(Case(
        When(type="x", then=1), 
        When(type="y", then=25), 
        When(type="z", then=-3),
        default=0,
        output_field=FloatField()
    ))
)

You could shorthand it like:您可以将其简写为:

sum(mapp.get(o['Type'],0) for o in data)

or simpler if you trust the data to have all valid types:如果您相信数据具有所有有效类型,则更简单:

sum(mapp[o['Type']] for o in data)

(Don't trust the data though) (尽管不要相信数据)

If the mapping x = 1, y = 25 etc... is coming from another table, you can use some SQL voodoo to let the database handle the summation for you.如果映射x = 1, y = 25等...来自另一个表,您可以使用一些 SQL voodoo 让数据库为您处理求和。 Other wise you have to (one way or another) loop through all results and sum them up.否则,您必须(以一种或另一种方式)遍历所有结果并将它们总结起来。

You could also theoretically just count the distinct amount of x , y and z in the table and have sum = x*count_of_x + y*count_of_y + z*count_of_z based on how the example is structured.理论上,您也可以只计算表中xyz的不同数量,并根据示例的结构使sum = x*count_of_x + y*count_of_y + z*count_of_z

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM