[Django]模型提高部分--聚合(group by)和条件表达式+数据库函数
前言:本文以学习记录的形式发表出来,前段时间苦于照模型聚合中group by 找了很久,官方文章中没有很明确的说出group by,但在文档中有提到!!!
正文(最后编辑于2016-11-12):
聚合:
LOrder.objects.values('com_chnl_name').annotate(Count('serv_id'))
#相当于select count(serv_id) from LOrder group by com_chnl_name
模型高级运用—条件表达式+数据库函数:
条件表达式:
from django.db.models import IntegerField,Sum,When,Q,Case #模型执行查询集
LOrder.objects.values('com_chnl_name').annotate(
cdma=Sum(
Case(When(Q(prod_offer_name__contains='语音CDMA') & Q(service_offer_name='订购'),then=1),
output_field=IntegerField())
),
)
#相当于select sum(case when prod_offer_name like’%.语音CDMA %’ and service_offer_name='订购' then 1 end) , com_chnl_name from LOrder group by com_chnl_name,该SQL语句也算是SQL中的中级部分. 其中&相当于and 对应的|相当于or
问题:聚合函数得到的结果如果不存在,那么会返回None,这对于结果全是数字的话,进行数字加减乘除很不方便,所以运用数据库函数将None改为0,以下例子:
数据库函数和条件表达式一起运用:
from django.db.models import IntegerField,Sum,When,Q,Case,Value as V #模型执行查询集
from django.db.models.functions import Coalesce #模型部分:数据库函数
LOrder.objects.values('com_chnl_name').annotate(
cdma_dg=Coalesce(Sum(
Case(When(Q(prod_offer_name__contains='语音CDMA') & Q(service_offer_name='订购'),then=1),
output_field=IntegerField())
),V(0)),
Coalesce¶
接受一个含有至少两个字段名称或表达式的列表,返回第一个非空的值(注意空字符串不被认为是一个空值)。每个参与都必须是相似的类型,所以掺杂了文本和数字的列表会导致数据库错误。
使用范例:
>>> # Get a screen name from least to most public
>>> from django.db.models import Sum, Value as V
>>> from django.db.models.functions import Coalesce
>>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
>>> author = Author.objects.annotate(
... screen_name=Coalesce('alias', 'goes_by', 'name')).get()
>>> print(author.screen_name)
Maggie
>>> # Prevent an aggregate Sum() from returning None
>>> aggregated = Author.objects.aggregate(
... combined_age=Coalesce(Sum('age'), V(0)),
... combined_age_default=Sum('age'))
>>> print(aggregated['combined_age'])
0
>>> print(aggregated['combined_age_default'])
None