我有一个模型,我使用Django ORM从表中提取平均值。我想围绕平均值,我该怎么做?
见下文我从YYYY-MM格式的按日期分组的价格模型中提取平均价格,我想自动提取四舍五入到最接近数字的平均值。
rs = Prices.objects.all.extra(select={
'for_date': 'CONCAT(CONCAT(extract( YEAR from for_date ), "-"),
LPAD(extract(MONTH from for_date), 2, "00"))'
}).values('for_date').annotate(price=Avg('price')).order_by('-for_date')
答案 0 :(得分:32)
以下是使用Django Aggregation topic guide中的Book模型在SQLite中舍入到小数点后两位的示例:
class Round(Func):
function = 'ROUND'
template='%(function)s(%(expressions)s, 2)'
Book.objects.all().aggregate(Round(Avg('price')))
这允许参数化圆函数(来自@ RichardZschech的答案):
class Round(Func):
function = 'ROUND'
arity = 2
Book.objects.all().aggregate(Round(Avg('price'), 2))
答案 1 :(得分:8)
改进@mrts答案。
这允许参数化圆函数:
class Round(Func):
function = 'ROUND'
arity = 2
Book.objects.all().aggregate(Round(Avg('price'), 2))
答案 2 :(得分:5)
基于先前的答案,我来到了此解决方案以使其适用于 PostgreSQL :
select * from
(SELECT 'N/A' as title,0 as ord FROM [Games]
UNION
SELECT [Games].[Title],1 as ord FROM Games)a
order by ord,title
答案 3 :(得分:1)
我需要同时具有 PostgreSQL 和 SQLite 的支持,而且还需要能够指定要保留的位数。
基于先前的答案:
class Round(Func):
function = 'ROUND'
arity = 2
# Only works as the arity is 2
arg_joiner = '::numeric, '
def as_sqlite(self, compiler, connection, **extra_context):
return super().as_sqlite(compiler, connection, arg_joiner=", ", **extra_context)
# Then one can use it as:
# queryset.annotate(avg_val=Round(AVG("val"), 6))
我本来希望更清洁的东西
if SQLITE:
arg_joiner=", "
elif PGSQL:
arg_joiner = '::numeric, '
else raise NotImplemented()
但没有找到方法,随时可以改善!
答案 4 :(得分:1)
Django具有Round
函数。有关更多详细信息,请参见the documentation