テーブルの一部のカラムの値をSumしていると、集計対象のレコードが存在しなかった場合、Sumの結果には通常Noneが返されます。
ここで処理が終わりであればよいのですが、その後そのSumした集計値を使っていろいろ計算を続ける場合、数値として認識されないため、その後の計算の結果もすべてNoneになってしまいます。
なので、もしSumした結果がNone(合計する行が存在しない場合も含め)であれば、0としておくと都合が良いことになります。
Coalesceを使います。
1 2 3 4 5 6 7 8 9 |
queryset = Model.objects.prefetch_related().all( ).annotate( total_good_weight = Sum('good_weight'), # 良品量の合計 total_defective_weight = Sum('defective_weight'), # 不良品量の合計 ).annotate( # 良品率を計算 # 不良品のSumの結果がNoneになってしまうと計算できないので、Coalesceでデフォルト値を0に指定する yield_rate=F('total_good_weight')*100/(F('total_good_weight') + Coalesce(F('total_defective_weight'),0) ) |
ポイントとしては、annotateが連続する場合、最後のannotateの中でCoalesceを使います。
annotateが連続しない場合、最初のSum時に、
1 2 3 4 5 |
queryset = Model.objects.prefetch_related().all( ).annotate( total_good_weight = Sum('good_weight'), # 良品量の合計 total_defective_weight = Coalesce(Sum('defective_weight'), 0), # 不良品量の合計 ) |
とやってもOKです。
参考サイト)