我有一张桌子student
。它有以下属性
name
,
age
,
school_passout_date
,
college_start_date
我需要一份报告,以了解avg number of days
学生在通过学校和开始上大学之间获得免费的机会。
目前,我正在为每个学生寻找天数并获得平均值而烦恼。
当记录集变大时,效率非常低。
Django ORM中是否有任何能力可以在两个日期之间给出总天数?
我正在寻找这样的东西。
Students.objects.filter(school_passed=True, started_college=True).annotate(total_days_between=Count('school_passout_date', 'college_start_date'), Avg_days=Avg('school_passout_date', 'college_start_date'))
最佳,
答案 0 :(得分:2)
数学上,根据(预期)事实,传递日期总是晚于开始日期,你可以平均取消所有开始日期和所有传递日期,并产生差异。< / p>
这为您提供了类似的解决方案
from django.db.models import Avg
avg_start_date = Students.objects.filter(school_passed=True, started_college=True).aggregate(Avg('school_start_date'))
avg_passout_date = Students.objects.filter(school_passed=True, started_college=True).aggregate(Avg('school_passout_date'))
avg_time_at_college = avg_passout_date - avg_start_date
答案 1 :(得分:1)
Django目前只接受4个函数的聚合:Max,Min,Count和et Average,所以这有点棘手。
然后解决方案使用方法extra。那样:
Students.objects.
extra(select={'difference': 'school_passout_date' - 'college_start_date'}).
filter('school_passed=True, started_college=True)
但是,你仍然必须在服务器端做平均值
答案 2 :(得分:1)
这个问题已经很久了,但现在Django ORM更先进了。
可以使用F()函数执行此操作。
from django.db.models import Avg, F
college_students = Students.objects.filter(school_passed=True, started_college=True)
duration = college_students.annotate(avg_no_of_days=Avg( F('college_start_date') - F('school_passout_date') )
答案 3 :(得分:0)
您可以这样做:
Model.objects.annotate(age=Cast(ExtractDay(TruncDate(Now()) - TruncDate(F('created'))), IntegerField()))
这使您可以使用整数值,例如,您可以执行以下操作:
from django.db.models import IntegerField, F
from django.db.models.functions import Cast, ExtractDay, TruncDate
qs = (
Model
.objects
.annotate(age=Cast(ExtractDay(TruncDate(Now()) - TruncDate(F('created'))), IntegerField()))
.annotate(age_bucket=Case(
When(age__lt=30, then=Value('new')),
When(age__lt=60, then=Value('current')),
default=Value('aged'),
output_field=CharField(),
))
)