如何过滤SQLAlchemy分组查询中avg_3d_perf>0的记录?
解决SQLAlchemy分组后过滤聚合字段的问题
要过滤分组后avg_3d_perf > 0的记录,核心是用**HAVING子句**而非WHERE,但需要正确引用聚合字段的表达式,以下是两种可行方案:
方案一:通过变量引用聚合字段(推荐,类型安全)
先将聚合字段定义为变量,再在having中直接引用该变量:
from sqlalchemy import func # 提前定义聚合字段变量 avg_3d_perf_col = func.avg(func.nullif(Signals_light.avg_3d_perf, 0)).label('avg_3d_perf') query = query.with_entities( func.max(Signals_light.id).label('id'), Signals_light.symbol, func.max(Signals_light.close).label('close'), func.max(Signals_light.volume).label('volume'), func.max(Signals_light.total_change).label('total_change'), func.max(Signals_light.strength).label('strength'), func.max(Signals_light.created_at).label('created_at'), func.max(Signals_light.window_mins).label('window_mins'), func.max(Signals_light.pattern).label('pattern'), func.max(Signals_light.pattern_type).label('pattern_type'), func.max(Signals_light.sentiment).label('sentiment'), avg_3d_perf_col, func.count(Signals_light.symbol).label('signals_count') ).group_by(Signals_light.symbol).having(avg_3d_perf_col > 0) results = query.all()
方案二:用text()直接引用别名
如果不想单独定义变量,可通过text()包装SQL字符串引用别名:
from sqlalchemy import func, text query = query.with_entities( func.max(Signals_light.id).label('id'), Signals_light.symbol, func.max(Signals_light.close).label('close'), func.max(Signals_light.volume).label('volume'), func.max(Signals_light.total_change).label('total_change'), func.max(Signals_light.strength).label('strength'), func.max(Signals_light.created_at).label('created_at'), func.max(Signals_light.window_mins).label('window_mins'), func.max(Signals_light.pattern).label('pattern'), func.max(Signals_light.pattern_type).label('pattern_type'), func.max(Signals_light.sentiment).label('sentiment'), func.avg(func.nullif(Signals_light.avg_3d_perf, 0)).label('avg_3d_perf'), func.count(Signals_light.symbol).label('signals_count') ).group_by(Signals_light.symbol).having(text('avg_3d_perf > 0')) results = query.all()
为什么之前的方法无效?
filter()不能用:filter()对应SQL的WHERE子句,仅能过滤分组前的原始行,无法引用分组后的聚合字段(如avg_3d_perf)。- 直接写
.having(avg_3d_perf > 0)无效:这里的avg_3d_perf是字符串,SQLAlchemy无法将其解析为合法的SQL表达式,必须用表达式对象或text()包装。
内容的提问来源于stack exchange,提问作者JP M
相关产品推荐
相关产品推荐

