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

SQLAlchemy如何基于过滤后的父表数据计算关联子表列平均值

实现方法

直接通过SQL层JOIN关联父子表,将父表过滤条件下推到数据库执行,配合聚合函数单次查询即可拿到结果,无需在Python内存中遍历计算,性能最优。

前置配置说明

一对多关系需要在子表配置指向父表主键的外键,否则ORM关联关系本身无法正常工作,补充后的完整模型定义如下:

from sqlalchemy import Column, Integer, ForeignKey, func
from sqlalchemy.orm import relationship, declarative_base

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    score = Column(Integer, nullable=False)
    children = relationship("Child", back_populates='parent')

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    data = Column(Integer, nullable=False)
    # 子表必填外键字段
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent", back_populates='children')

核心查询代码

计算所有符合父表分数条件的子表记录data字段平均值,仅需一次数据库查询:

# 直接返回数值类型的平均值结果
avg_result = session.query(func.avg(Child.data))\
    .join(Child.parent)\
    .filter(Parent.score > 70, Parent.score < 100)\
    .scalar()

逻辑说明

  • 查询直接从子表聚合逻辑出发,通过JOIN关联对应父表记录,过滤条件直接作用于父表score字段,所有筛选、聚合计算全在数据库层完成,仅返回最终计算结果,不会把全量符合条件的父、子表记录加载到Python内存,效率远高于遍历ORM对象手动计算的方案。
  • 因为已经通过relationship配置了父子表关联关系,join(Child.parent)会自动识别关联外键,不需要手动写Child.parent_id == Parent.id的关联条件,减少字段写错的概率。

扩展场景:按父表分组计算单条父记录对应的子表平均值

如果需要拿到每个符合分数条件的Parent记录,同时返回它关联的Child记录的data平均值,可以用分组聚合实现,同样是单次查询完成:

result_list = session.query(
    Parent,
    func.avg(Child.data).label("child_avg_data")
)\
    .join(Parent.children)\
    .filter(Parent.score >70, Parent.score <100)\
    .group_by(Parent.id)\
    .all()

# 结果遍历示例
for parent, avg_data in result_list:
    print(f"父记录id:{parent.id}, 分数:{parent.score}, 关联子项data平均值:{avg_data}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:27:29