简体   繁体   English

Flask SQLAlchemy 中所有组的第一行

[英]First row of all groups in Flask SQLAlchemy

I want to group the database by gauge_id and then get the row having maximum time_col .我想按gauge_id对数据库进行gauge_id ,然后获取具有最大time_col的行。 This is my current code:这是我当前的代码:

rain_gauge_datas = db.session.query(DataEntry.gauge_id, func.max(DataEntry.time_col)).group_by(DataEntry.gauge_id).all()

But I am only able to get both gauge_id and time_col .但我只能同时获得gauge_idtime_col When I add another column (reading), like this:当我添加另一列(阅读)时,如下所示:

rain_gauge_datas = db.session.query(DataEntry.gauge_id, DataEntry.reading, func.max(DataEntry.time_col)).group_by(DataEntry.gauge_id).all()

it gives this error.它给出了这个错误。

column "data_entry.reading" must appear in the GROUP BY clause or be used in an aggregate function

How do I return the top row of each groups?如何返回每个组的顶行? Thanks in advance.提前致谢。

One way to do this would be with a common table expression (CTE).一种方法是使用公用表表达式(CTE)。 The CTE creates a virtual table of the group by resultset which we can then join against. CTE 根据结果集创建组的虚拟表,然后我们可以加入该表。

The SQL would be SQL将是

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;

The SQLAlchemy equivalent would be SQLAlchemy 的等价物是

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
))

(the above example uses "pure" SQLAlchemy rather than Flask-SQLAlchemy - it should be enough to replace sa. with db. and session with db.session to get it working in Flask_SQLAlchemy) (上面的示例使用“纯”SQLAlchemy 而不是 Flask-SQLAlchemy - 用db.替换sa. db.和用db.session替换session以使其在 Flask_SQLAlchemy 中工作就足够了)

It's worth noting that CTEs were not handled efficiently in Postgresql until v12, so if you are on an earlier version it may be better to inline the CTE as a subquery.值得注意的是,直到 v12,Postgresql 中的 CTE 才得到有效处理,因此如果您使用的是早期版本,最好将 CTE 作为子查询内联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM