首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQLAlchemy中所有组的第一行

SQLAlchemy中所有组的第一行
EN

Stack Overflow用户
提问于 2021-07-11 10:13:46
回答 1查看 830关注 0票数 0

我希望按gauge_id对数据库进行分组,然后获得具有最大time_col的行。这是我目前的代码:

代码语言:javascript
运行
复制
rain_gauge_datas = db.session.query(DataEntry.gauge_id, func.max(DataEntry.time_col)).group_by(DataEntry.gauge_id).all()

但我只能得到gauge_idtime_col。当我添加另一列(阅读)时,如下所示:

代码语言:javascript
运行
复制
rain_gauge_datas = db.session.query(DataEntry.gauge_id, DataEntry.reading, func.max(DataEntry.time_col)).group_by(DataEntry.gauge_id).all()

它产生了这个错误。

代码语言:javascript
运行
复制
column "data_entry.reading" must appear in the GROUP BY clause or be used in an aggregate function

如何返回每个组的顶部行?提前谢谢。

EN

Stack Overflow用户

回答已采纳

发布于 2021-07-11 13:37:24

要做到这一点,一种方法是使用公共表表达式 (CTE)。CTE通过结果集创建组的虚拟表,然后我们可以对其进行连接。

SQL将是

代码语言:javascript
运行
复制
with cte as (
    select gauge_id, max(time_col) as max_time
    from data_entries
    group by gauge_id
)

select d.* from data_entries d
join cte 
on d.gauge_id = cte.gauge_id 
and d.time_col = cte.max_time;

SQLAlchemy的等价物是

代码语言:javascript
运行
复制
cte = (session.query(DataEntry.gauge_id, sa.func.max(DataEntry.time_col).label('max_time'))
              .group_by(DataEntry.gauge_id)
              .cte(name='cte'))
query = session.query(DataEntry).join(cte, sa.and_(
    DataEntry.gauge_id == cte.c.gauge_id,
    DataEntry.time_col == cte.c.max_time
))

(上面的示例使用“纯”SQLAlchemy,而不是使用sa. -SQLAlchemy-用db.代替sa.,用db.session代替session使其在Flask_SQLAlchemy中工作就足够了)

值得注意的是,在Postgresql中直到v12才能有效地处理CTE,所以如果您使用的是早期版本,最好将CTE内联为子查询。

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68335261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档