我正在尝试运行一个大致等于的聚合查询:
select sum(impressions) as impressions, sum(clicks) as clicks, sum(clicks)/sum(impressions) as ctr from stats group by product order by ctr;
使用的数据库是PostgreSQL.
我做了这个查询表达式(Django 1.9):
Stats.objects.values('product').annotate( impressions = models.Sum('impressions'), clicks = models.Sum('clicks'), ctr = models.ExpressionWrapper( models.F('clicks')/models.F('impressions')), output_field = models.FloatField() ) ).order_by('ctr')
它有两个问题:
ctr
是0.0因为它在数据库级别划分整数
division by zero
如果展示次数为0,则会抛出
什么是正确的解决方案?
使用条件表达式:
from django.db.models import Case, F, Sum, When Stats.objects.values('product').annotate( tot_impressions=Sum('impressions'), tot_clicks=Sum('clicks') ).annotate( ctr=Case(When(tot_impressions=0, then=None), # or other value, e.g. then=0 # 1.0*... is to get float in SQL default=1.0*F('tot_clicks')/F('tot_impressions'), output_field=models.FloatField()) ).order_by('ctr')