Django聚合注释查询
发布时间:2020-12-20 13:35:28 所属栏目:Python 来源:网络整理
导读:这就是我想让Django在SQL中生成的: select avg(subquery.countval) from (select count(something) countval,user_id from foo group by user_id ) subquery 我认为这应该基于Annotated聚合文档与Django一起使用: Foo.objects.all().values('user_id'). a
这就是我想让Django在SQL中生成的:
select avg(subquery.countval) from ( select count(something) countval,user_id from foo group by user_id ) subquery 我认为这应该基于Annotated聚合文档与Django一起使用: Foo.objects.all().values('user_id'). annotate(countval=Count('id')). aggregate(Avg('countval')) 问题是Django 4.x没有生成正确的查询.你会得到类似的东西: SELECT FROM (SELECT foo.user_id as user_id,COUNT(foo.id) AS countval from foo group by foo.user_id) 有任何想法吗?我通过源调试,但不明显出了什么问题. 解决方法
我无法用纯Django代码完成它,但这是我能做的最好的,尽可能多地取决于Django代码而不是原始sql.
from django.db import connection from django.db.models import Count def get_average_count(klass,field_name): foo = klass.objects.values(field_name).annotate(countval=Count('id')) query = "SELECT AVG(subquery.countval) FROM (%s) subquery" % str(foo.query) cursor = connection.cursor() cursor.execute(query) return float(cursor.fetchone()[0]) 这将执行您说要生成的确切SQL语句.它也完全独立于您正在使用的SQL后端,并且对于具有反向ForeignKey或ManyToMany关系的所有类完全可重用(yay DRY). 如果你真的不想使用原始SQL,另一种选择是计算Django的平均值: from __future__ import division # no need to cast to float now def get_average_count(klass,field_name): counts = klass.objects.values(field_name).annotate(countval=Count('id')). values_list('countval',flat=True) return reduce(lambda x,y: x + y / len(counts),counts,0) 如果您计划在数据库中拥有大型数据集,则可能需要检查是否存在任何性能差异. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |