Django ORM 高级查询之Case-When
在开发中我们极有可能遇到以下情况
金额流水表 tab_money_stream
Id | Money | IsPositive | push_datetime |
---|---|---|---|
uuid | 10 | f | 2020-11-11 |
uuid | 5 | t | 2020-11-11 |
这个时候我们需要统计某个用户某天一共赚了多少钱,这个时候我们使用sql来完成这件事情是非常简单的,如下:
select
sum(
case is_positive
when true
then `money`
else 0
end)-
sum(
case is_positive
when false
then `money`
else 0
end) as balance
from
tab_money_stream
where
to_char(push_datetime, 'YYYY-MM-DD') = '2020-11-11'
但是我们使用Django ORM 来完成这个事情的时候就会又很多小伙伴抓狂了,因为在django的文档内对这一块的描述并不多,导致很多小伙伴不太明白怎么弄,接下来我们用Django 来实现一下这个sql
from django.db import connection
from django.db.models import Prefetch, Q, Sum, Case, When, F, Value, FloatField, Model
class MoneyStreamModel(Model):
money = models.FloatField(null=True, verbose_name='金额')
is_positive = models.BooleanField(default=True, verbose_name='增加资金')
push_datetime = models.DateTimeField(default=timezone.now, verbose_name='发布时间')
# 主要代码
MoneyStreamModel.objects.filter(push_datetime__startswith=date).aggregate(
balance=Sum(Case(When(is_positive=True, then=F('money')), default=Value(0.0), output_field=FloatField())) -
Sum(Case(When(is_positive=False, then=F('money')), default=Value(0.0),output_field=FloatField()))
)
# 输出 {'balance':5.0}
print(connection.queries[-1]['sql'])
# SELECT (SUM(CASE WHEN "tab_money_stream"."is_positive" THEN "tab_money_stream"."money" ELSE 0.0 END) - SUM(CASE WHEN NOT "tab_money_stream"."is_positive" THEN "tab_money_stream"."money" ELSE 0.0 END)) AS "clazz_total_score" FROM "tab_money_stream" WHERE ("tab_money_stream"."push_datetime"::text LIKE '2022-03-29%')
解释一下
Case
和When
在代码中如何对应于sql
# sql:
'''
case is_positive
when false
then `money`
else 0
end
'''
Case(When(is_positive=True, then=F('money')), default=Value(0.0), output_field=FloatField())
# 以他的值为条件 成立则返回then 否则返回default 以output_field类型输出
Case-When 可以配合聚合函数使用,以实现很多高级查询。
文章到此结束,希望对各位有所帮助,我是老四下一篇见
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Tioit Wang
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果