【问题标题】:sqlalchemy - grouping items and iterating over the sub-listssqlalchemy - 对项目进行分组并遍历子列表
【发布时间】:2010-11-19 17:52:03
【问题描述】:

考虑这样的表格:

| Name       | Version | Other |
| ---------------------|-------|
| Foo        | 1       | 'a'   |
| Foo        | 2       | 'b'   |
| Bar        | 5       | 'c'   |
| Baz        | 3       | 'd'   |
| Baz        | 4       | 'e'   |
| Baz        | 5       | 'f'   |
--------------------------------

我想编写一个 sqlalchemy 查询语句来列出最大版本的所有项目(作为映射器对象,而不仅仅是名称列):Foo-2-b, Bar-5-c, Baz-5-f。我知道我必须使用group_by 方法,但除此之外,我对如何检索子列表(然后找到最大元素)感到困惑。 SQLAlchemy 文档对此显然不是很清楚。

在实际场景中,还有许多其他列(如“其他”) - 这就是为什么我需要返回实际的行对象(映射器类)而不仅仅是“名称”值。

【问题讨论】:

    标签: python sql sqlalchemy


    【解决方案1】:

    如果您需要完整的对象,您需要在子查询中按名称选择最大版本并加入:

    max_versions = session.query(Cls.name, func.max(Cls.version).label('max_version'))\
                          .group_by(Cls.name).subquery()
    objs = session.query(Cls).join((max_versions,
               and_(Cls.name == max_versions.c.name,
                    Cls.version == max_versions.c.max_version)
           )).all()
    

    这将导致如下结果:

    SELECT tbl.id AS tbl_id, tbl.name AS tbl_name, tbl.version AS tbl_version
    FROM tbl JOIN (SELECT tbl.name AS name, max(tbl.version) AS max_version
    FROM tbl GROUP BY tbl.name) AS anon_1 ON tbl.name = anon_1.name AND tbl.version = anon_1.max_version
    

    请注意,如果有多个具有最大版本的行,您将获得多个具有相同名称的行。

    【讨论】:

    • 谢谢; (Name, version) 是一个主键集。
    【解决方案2】:

    这是您可以使用engine.execute 命令调用的 SQL:

    select
        t1.*
    from
        table t1
        inner join 
            (select
                Name,
                max(version) as Version
             from
                table
             group by
                name) s on
            s.name = t1.name
            and s.version = t1.version
    

    【讨论】:

    • 实际上我想要整个“行”对象(映射器类对象),而不仅仅是名称。实际表包含其他几个感兴趣的列。
    • .. 并且此行对象应对应于具有最大版本的行对象。明白了吗?
    猜你喜欢
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2021-05-12
    • 2014-04-01
    • 1970-01-01
    相关资源
    最近更新 更多