Django查询中F()求和遇Null返回None,需替换为0的解决方法
问题:Django查询中如何将Null值转为0后求和?
我编写了如下Django查询代码:
sq_edit = UsulanRekomposisiData.objects.filter(file=draft, prk=OuterRef('prk')) cols = ['edit_jan', 'edit_feb', 'edit_mar', 'edit_apr', 'edit_mei', 'edit_jun', 'edit_jul', 'edit_aug', 'edit_sep', 'edit_okt', 'edit_nov', 'edit_des'] expr = reduce(add, (F(col) for col in cols)) lrpa = monitoring. annotate( edit_jan = sq_edit.values('jan'),edit_feb = sq_edit.values('feb'),edit_mar = sq_edit.values('mar'),edit_apr = sq_edit.values('apr'), edit_mei = sq_edit.values('mei'),edit_jun = sq_edit.values('jun'),edit_jul = sq_edit.values('jul'),edit_aug = sq_edit.values('aug'), edit_sep = sq_edit.values('sep'),edit_okt = sq_edit.values('okt'),edit_nov = sq_edit.values('nov'),edit_des = sq_edit.values('des') ).annotate(sum_edit = expr)
我想要计算各月度edit字段的总和,但因部分字段值为Null,sum_edit始终返回None。我希望将Null值视为0参与求和,尝试了0 if F(col) is None else F(col) for col in cols等写法但无效,执行结果如下:
for data in lrpa: print(data.prk.no_prk, data.sum_edit, data.edit_jan, data.edit_okt) #RESULT 2019.USLS.36.002 None None 112 2019.USLS.64.001 None None 123 2019.USLU.1.002 None None None 2021.USLW.202.003 None None None 2022.USLW.291.001 None None None 2019.USLS.63.001 None None None 2019.USLU.12.002 None None None 2019.USLU.13.002 None None None 2020.USLS.148.003 None None None 2021.USLU.24.013 None None None 2021.USLW.15.006 None None None 2021.USLW.208.003 None None None 2022.USLW.152.001 None None None 2022.USLW.296.001 None None None
请问如何实现将Null转为0后求和?
解决方案
在Django中,处理Null值转为0求和需要用到Coalesce数据库函数,它会返回参数列表中的第一个非Null值。具体修改步骤如下:
- 首先导入所需的函数:
from django.db.models import Coalesce, Value
- 修改求和表达式,用
Coalesce包裹每个F(col),指定默认值为0:
expr = reduce(add, (Coalesce(F(col), Value(0)) for col in cols))
- 同时,子查询返回的月度字段也可能为Null,需要同样用
Coalesce处理,避免这些字段本身为Null影响求和:
lrpa = monitoring.annotate( edit_jan=Coalesce(sq_edit.values('jan'), Value(0)), edit_feb=Coalesce(sq_edit.values('feb'), Value(0)), edit_mar=Coalesce(sq_edit.values('mar'), Value(0)), edit_apr=Coalesce(sq_edit.values('apr'), Value(0)), edit_mei=Coalesce(sq_edit.values('mei'), Value(0)), edit_jun=Coalesce(sq_edit.values('jun'), Value(0)), edit_jul=Coalesce(sq_edit.values('jul'), Value(0)), edit_aug=Coalesce(sq_edit.values('aug'), Value(0)), edit_sep=Coalesce(sq_edit.values('sep'), Value(0)), edit_okt=Coalesce(sq_edit.values('okt'), Value(0)), edit_nov=Coalesce(sq_edit.values('nov'), Value(0)), edit_des=Coalesce(sq_edit.values('des'), Value(0)) ).annotate(sum_edit=expr)
修改后,所有Null值都会被替换为0,求和时sum_edit将返回正确的数值而非None。
内容的提问来源于stack exchange,提问作者Andi Fathul Mukminin
相关产品推荐
相关产品推荐

