我有一个条件查询问题。我一直在阅读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}}我的查询,它没有改变结果。
答案 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'),
)