(使用 django 1.11.2、python 2.7.10、mysql 5.7.18)
如果我们想象一个简单的模型:
class Event(models.Model):
happened_datetime = DateTimeField()
value = IntegerField()
运行类似以下内容的最优雅(也是最快)的方式是什么:
res = Event.objects.all().aggregate(
Avg('happened_datetime')
)
但这将能够提取查询集所有成员的平均一天中的时间。像这样的东西:
res = Event.objects.all().aggregate(
AvgTimeOfDay('happened_datetime')
)
是否可以直接在数据库上执行此操作?即,无需为每个查询集成员运行长循环客户端?
编辑:
可能有一个解决方案,沿着这些思路,使用原始 SQL:
select sec_to_time(avg(time_to_sec(extract(HOUR_SECOND from happened_datetime)))) from event_event;
就性能而言,在笔记本电脑上运行约 23k 行的时间为 0.015 秒,未进行优化等。假设可以产生准确/正确的结果,并且由于时间只是次要因素,因此可以我正在使用它?
最佳答案
向您的模型添加另一个整数字段,该字段仅包含从 happened_datetime
中提取的一天中的小时。
创建/更新模型实例时,每当设置/更新 happened_datetime
时,您都需要相应地更新此新字段。例如,您可以通过读取datetime.datetime.hour
来提取一天中的小时数。或者使用 strftime 创建您喜欢的值。
然后聚合应该按照您的建议进行。
编辑:
Django 的 ORM 将 Extract()
作为函数。适合您的用例的文档示例:
>>> # How many experiments completed in the same year in which they started?
>>> Event.objects.aggregate(
... happenend_datetime__hour=Extract('happenend_datetime', 'hour'))
(未经测试!) https://docs.djangoproject.com/en/1.11/ref/models/database-functions/#extract
关于python - Django - 跨查询集的 DatetimeField 时间聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46176919/