Django ORM IF声明

时间:2016-06-28 19:43:07

标签: django orm aggregate

我有这张桌子

enter image description here

使用SQL查询,我可以获得有关avery汽车的总“金额”的汇总信息,以及“已检查”|“未核算”行的数量以及已完成检查一辆汽车所有行的标志:

SELECT 
car_id 
, SUM(amount) as total_amount
, Sum(IF(checked=1,1,0)) as already_checked
, Sum(IF(checked=0,1,0)) as not_cjecked
, IF(Sum(IF(checked=0,1,0))=0,1,0) as check_finished
FROM 
    refuels_flow
GROUP BY car_id

结果:

+--------+--------------+-----------------+-------------+----------------+
| car_id | total_amount | already_checked | not_cjecked | check_finished |
+--------+--------------+-----------------+-------------+----------------+
|      1 | 1300         | 1               | 12          |              0 |
|      2 | 300          | 3               | 0           |              1 |
+--------+--------------+-----------------+-------------+----------------+

问题是 - 我如何使用Django ORM(不使用原始查询)来做到这一点?

1 个答案:

答案 0 :(得分:1)

要获得相同的SQL输出,可以使用以下查询集:

already_checked = Sum(Func('checked', function='IF', template='%(function)s(%(expressions)s=0, 0, 1)'))
not_checked = Sum(Func('checked', function='IF', template='%(function)s(%(expressions)s=0, 1, 0)'))
check_finished = Func(
        not_checked,
        function='IF', template='%(function)s(%(expressions)s=0, 1, 0)'
)
Refuels.objects.values('car_id').annotate(
    total_amount=Sum('amount'),
    already_checked=already_checked,
    not_checked=not_checked,
    check_finished=check_finished
)

检查doc表达式以获取更多信息。

现在,already_checked可以简化为:

already_checked = Sum('checked')

而不是使用not_checkedcheck_finished注释,您可以注释计数并在Python中轻松计算它们,例如:

qs = Refuels.objects.values('car_id').annotate(
    count_for_car=Count('car_id'),
    total_amount=Sum('amount'),
    already_checked=Sum('checked'),
)

for entry in qs:
    not_checked = entry['count_for_car'] - entry['already_checked']
    check_finished = not_checked == 0