SqlAlchemy group_by 并返回最大日期

Posted

技术标签:

【中文标题】SqlAlchemy group_by 并返回最大日期【英文标题】:SqlAlchemy group_by and return max date 【发布时间】:2018-01-28 06:23:20 【问题描述】:

我有一张这样的桌子

identifier date        value
A          2017-01-01  2 
A          2017-01-02  1
A          2017-01-03  7
B          2017-01-01  2 
B          2017-01-02  7
B          2017-01-03  3

我正在尝试选择每个标识符的最大日期,例如:

identifier date        value
A          2017-01-03  7
B          2017-01-03  3

谢谢

【问题讨论】:

这是一个非常常见的问题,并产生了自己的标签:greatest-n-per-group。试着搜索一下。解决方案可能有点特定于数据库,因此请至少提供该信息。 @IljaEverilä 我看到了,但是 sql alchemy 没有等价物(python 等价物) 我知道这是不真实的。例如,这是一个 Postgresql 解决方案:***.com/questions/44069023/…,尽管它缺少标签。在 SQLA 中实现纯 SQL 解决方案也相当简单。 @IljaEverilä 不确定您在所指问题中看到的分组依据。我的 SQL 技能很差(完全公开),合并半相似的解决方案并使其工作并不总是那么容易 Nowhere 作为子句,因为它使用 Postgresql 特定的 DISTINCT ON ... ORDER BY 组合来有效地实现每组最大的 n。如果不熟悉术语,搜索 SQL 解决方案确实令人生畏。 【参考方案1】:

在SQLAlchemy核心中,可以使用以下代码实现-

import sqlalchemy as db

query = db.select([
    TABLE.c.identifier,
    db.func.max(USERS.c.date),
    TABLE.c.value,
]).group_by(TABLE.c.identifier)

result = engine.execute(query).fetchall()

【讨论】:

【参考方案2】:

使用子查询:

SELECT t1.identifier, t1.date, t1.value FROM table t1
JOIN
(
    SELECT identifier, MAX(date) maxdate
    FROM table
    GROUP BY identifier
) t2
ON t1.identifier = t2.identifier AND t1.date = t2.maxdate;

在 SQLAlchemy 中:

from sqlalchemy import func, and_

subq = session.query(
    Table.identifier,
    func.max(Table.date).label('maxdate')
).group_by(Table.identifier).subquery('t2')

query = session.query(Table).join(
    subq,
    and_(
        Table.identifier == subq.c.identifier,
        Table.date == subq.c.maxdate
    )
)

【讨论】:

@Ruben Flam-Shepherd 不要更改代码;发表评论或您自己的答案【参考方案3】:

在 orm 中,您几乎可以像在 mysql 中那样编写它

result = session.query(Table,func.max(Table.date)).group_by(Table.identifier)
for row,i in result:
    print(row.date,row.value,row.identifier,i)

【讨论】:

【参考方案4】:

使用 ORM,您可以使用 over 函数,它实际上是一个窗口函数:

session \
    .query(Table, func.max(Table.date)
           .over(partition_by=Table.identifier, order_by=Table.value))

它返回一个元组(table_instance,latest_datetime)。 order_by 在这种情况下是可选的。

带有 SQL 表达式的 same。

【讨论】:

以上是关于SqlAlchemy group_by 并返回最大日期的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy的group_by和order_by的区别

四十三:数据库之SQLAlchemy之group_by和having子句

将 SqlAlchemy group_by/func 查询转换为 GraphQL

sqlAlchemy 按DateTime字段的年或月进行group_by查询

Ecto查询在datetime字段上执行group_by MONTH并返回元组列表

SqlAlchemy 的使用