You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask模型按15分钟时间段分组求平均行程时长的实现方案

没问题,我来帮你搞定这个按15分钟时间段分组计算平均行程时长的需求~

方案一:直接在查询中计算时间段(无需修改模型)

如果你不想改动现有模型,可以直接在查询语句里用SQL函数计算小时和15分钟区间,这样不用额外添加字段就能得到想要的结果:

from sqlalchemy import func, extract

# 执行分组查询
results = db.session.query(
    # 提取出发小时
    extract('hour', Journey.departure_time).label('departure_hour'),
    # 将分钟按15分钟分段:0对应00-14,1对应15-29,以此类推
    func.floor(extract('minute', Journey.departure_time) / 15).label('departure_quarter'),
    # 计算每组的平均行程时长
    func.avg(Journey.travel_duration).label('avg_duration')
).group_by(
    extract('hour', Journey.departure_time),
    func.floor(extract('minute', Journey.departure_time) / 15)
).all()

这种方式的好处是快速实现,不需要修改现有模型结构,适合临时或一次性的查询需求。

方案二:给模型添加混合属性(支持实例访问+SQL查询)

如果你希望像使用普通字段一样调用departure_hour和departure_quarter,可以给Journey模型添加混合属性(hybrid property),这样既支持Python实例层面的访问,也能在SQL查询中正常使用:

from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import func, extract

class Journey(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    origin_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    destination_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    departure_time = db.Column(db.DateTime, nullable=False)
    travel_duration = db.Column(db.Integer, nullable=False)
    origin = db.relationship("Location", foreign_keys=[origin_id])
    destination = db.relationship("Location", foreign_keys=[destination_id])

    @hybrid_property
    def departure_hour(self):
        # Python实例层面:直接取出发时间的小时数
        return self.departure_time.hour

    @departure_hour.expression
    def departure_hour(cls):
        # SQL查询层面:用extract函数提取小时
        return extract('hour', cls.departure_time)

    @hybrid_property
    def departure_quarter(self):
        # Python实例层面:分钟//15得到0-3的区间标识
        return self.departure_time.minute // 15

    @departure_quarter.expression
    def departure_quarter(cls):
        # SQL查询层面:用floor函数计算15分钟区间
        return func.floor(extract('minute', cls.departure_time) / 15)

添加完混合属性后,你就可以完全按照自己最初的想法写查询了:

results = db.session.query(
    Journey.departure_hour,
    Journey.departure_quarter,
    func.avg(Journey.travel_duration).label('avg_duration')
).group_by(Journey.departure_hour, Journey.departure_quarter).all()

这种方式的优势是代码更整洁,属性可以复用在其他查询或业务逻辑中,同时兼顾了Python代码和SQL查询的一致性。

额外优化:生成直观的时间段标签

如果需要更易读的时间段描述(比如10:00-10:14),可以在查询中直接拼接字符串:

results = db.session.query(
    func.concat(
        extract('hour', Journey.departure_time),
        ':',
        func.lpad(func.floor(extract('minute', Journey.departure_time)/15)*15, 2, '0'),
        '-',
        extract('hour', Journey.departure_time),
        ':',
        func.lpad((func.floor(extract('minute', Journey.departure_time)/15)+1)*15 -1, 2, '0')
    ).label('time_slot'),
    func.avg(Journey.travel_duration).label('avg_duration')
).group_by('time_slot').all()

返回的结果会直接显示类似10:00-10:14的时间段,更便于理解。

内容的提问来源于stack exchange,提问作者BenScape

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:40:23