【问题标题】:SqlAlchemy group_by and return max dateSqlAlchemy group_by 并返回最大日期
【发布时间】: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 解决方案:stackoverflow.com/questions/44069023/…,尽管它缺少标签。在 SQLA 中实现纯 SQL 解决方案也相当简单。
  • @IljaEverilä 不确定您在所指问题中看到的分组依据。我的 SQL 技能很差(完全公开),合并半相似的解决方案并使其工作并不总是那么容易
  • Nowhere 作为子句,因为它使用 Postgresql 特定的 DISTINCT ON ... ORDER BY 组合来有效地实现每组最大的 n。如果不熟悉术语,搜索 SQL 解决方案确实令人生畏。

标签: python sqlalchemy greatest-n-per-group


【解决方案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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-12
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 1970-01-01
        • 2022-01-03
        相关资源
        最近更新 更多