为什么Case /当取消我的values()annotate()查询的结果?

时间:2017-08-21 16:44:04

标签: python django

我有一个条件查询问题。我一直在阅读https://docs.djangoproject.com/en/1.11/topics/db/aggregation/https://docs.djangoproject.com/en/1.11/ref/models/conditional-expressions/,但似乎无法解决这个问题。

我们说我有一个订单型号,我希望按用户分组付款明细。

这是订单模型:

class Order(models.Model):    
    CASH = 'c'
    CARD = 'a'
    PAYMENT_TYPES = (
        (CASH, 'Cash'),
        (CARD, 'Card'),
    )
    user = models.ForeignKey(User, on_delete=models.PROTECT, null=True, blank=True)
    payment_type = models.CharField(max_length=1, choices=PAYMENT_TYPES)
    grand_total = models.DecimalField(max_digits=8, decimal_places=2)

这是一个值()+ annotate()查询,显示每个用户的总数:

query = Order.objects.values(
    'user'
).annotate(
    total=Sum('grand_total'),
)

结果,到目前为止一切顺利:

User     Total
--------------
User 1   300
User 2   250

但是,当我向查询添加Case / When条件时:

query = Order.objects.values(
    'user'
).annotate(
    cash=Case(When(payment_type=Order.CASH, then=Sum('grand_total')), default=Value(0)),
    card=Case(When(payment_type=Order.CARD, then=Sum('grand_total')), default=Value(0)),
    total=Sum('grand_total'),
)

我得到了这个结果,这不是我想要的结果:

User     Cash      Card      Total
----------------------------------
User 1   300       0         300
User 2   200       0         200
User 2   0         50        50

当然,这就是我想要的:

User     Cash      Card      Total
----------------------------------
User 1   300       0         300
User 2   200       50        250

为什么是Case /在撤消GROUP BY时值()给我?

注意:订单模型没有默认排序,但为了以防万一,在使用值()时阅读https://docs.djangoproject.com/en/1.11/topics/db/aggregation/#interaction-with-default-ordering-or-order-by,我尝试添加.order_by()和{{ 1}}我的查询,它没有改变结果。

1 个答案:

答案 0 :(得分:0)

原来我的聚合函数应该包装我的Case语句,而不是反过来。

query = Order.objects.values(
    'user',
).annotate(
    cash=Sum(Case(When(payment_type=Order.CASH, then=F('grand_total')))),
    card=Sum(Case(When(payment_type=Order.CARD, then=F('grand_total')))),
    total=Sum('grand_total'),
)