django-sum,如果另一列不同

wkftcu5l  于 2021-07-26  发布在  Java
关注(0)|答案(11)|浏览(307)

我在djagno有两张table

class Item(models.model):
    name = models.TextField()
    type = models.ForeignKey(ItemType)
    quantity = models.IntegerField()

class ProductionRecord(models.model):
    item = models.ForeignKey(Item)
    done = models.IntegerField()

我想做的是按类型对项目进行分组,求出所需项目的总数,然后求出所生产项目的总数。
我很接近,但我遇到的问题是 .annotate(Sum("quantity")) 如果一个项目有多个生产记录,它将对每个记录的数量再次求和。
下面是我在加入表之后和分组之前的当前数据集的示例。 `+--------+--------+

nue99wik

nue99wik2#

--+ | ItemId | TypeId | ItemQuantity | ProductionRecordDone | +--------+--------+

x7rlezfr

x7rlezfr4#

--+ | 1257 | 7 | 4 | 1 | | 1257 | 7 | 4 | 4 | | 1259 | 7 | 4 | 4 | | 1261 | 7 | 4 | 0 | | 1263 | 7 | 4 | 4 | | 1265 | 7 | 4 | 0 | +--------+--------+

vwkv1x7d

vwkv1x7d6#

--+当对数量列进行普通求和时,它返回24,因为它是对item id=1257求和两次。 但分组后我想返回的是:+--------+

nfeuvbwi

nfeuvbwi7#

----+------+ | TypeId | ItemQuantity | Done | +--------+

eanckbw9

eanckbw98#

----+------+ | 7 | 20 | 13 | +--------+

5ssjco0h

5ssjco0h9#

----+------+` 这里是我当前的python代码,供参考

Item.objects.values("type__name", "type__id") \
            .annotate(total_done=Coalesce(Sum("productionrecord__done"), 0),
                      total_quantity=Coalesce(Sum("quantity",), 1))

是否有任何代码可用于只对itemid不同的行中的数量求和?

yzckvree

yzckvree10#

尝试:

queryset = Item.objects.values("type__name", "type__id") \
    .filter(productionrecord__done=True) \
    .annotate(total_done=Count("*"),
              total_quantity=Sum("quantity"))

请出示证件 queryset.query 如果它不能按预期工作。

idfiyjo8

idfiyjo811#

这不能在一个查询中完成,因为在与生产记录进行外部连接时,数量之和将复合。但是,您可以执行两个查询,并合并dict:

data = {}
    quantities = (
        Item.objects.order_by("type_id")
        .values("type_id")
        .annotate(to_produce=Coalesce(Sum("quantity"), 1),)
    )
    for item in quantities:
        type_id = item.pop("type_id")
        data[type_id] = item
    done = (
        Item.objects.order_by("type_id")
        .values("type_id")
        .annotate(done=Coalesce(Sum("productionrecord__done"), 1),)
    )
    for item in done:
        item_type_id = item.pop("type_id")
        data[type_id].update(item)

    for type_id, numbers in data.items():
        print(type_id, numbers.get("to_produce"), numbers.get("done"))

相关问题