如何从SQLAlchemy获取最年轻的对象?

时间:2015-03-31 00:52:00

标签: python sqlalchemy

我表格中的每一行都有一个日期。日期不是唯一的。同一日期不止一次出现。 我希望获得最年轻的所有对象。

我的解决方案有效,但我不确定这是否是一种优雅的SQLAlchemy方法。

query = _session.query(Table._date) \
            .order_by(Table._date.desc()) \
            .group_by(Table._date)
# this is the younges date (type is date.datetime)
young = query.first()

query = _session.query(Table).filter(Table._date==young)
result = query.all()

是不是有办法将所有这些放在一个查询对象或类似的东西中?

2 个答案:

答案 0 :(得分:1)

您需要having clause,并且需要导入max功能 那么你的查询将是:

from sqlalchemy import func

stmt = _session.query(Table) \
               .group_by(Table._date) \
               .having(Table._date == func.max(Table._date)

这会生成如下的sql语句。

SELECT my_table.* 
FROM my_table 
GROUP BY my_table._date 
HAVING my_table._date = MAX(my_table._date)

如果使用select构造sql语句,则可以使用查看在您的案例中生成的sql。 *我不确定这是否适用于语句query

str(stmt)

答案 1 :(得分:0)

使用子查询执行此操作的两种方法:

# @note: do not need to alias, but do in order to specify `name`
T1 = aliased(MyTable, name="T1")

# version-1:
subquery = (session.query(func.max(T1._date).label("max_date"))
            .as_scalar()
            )
# version-2:
subquery = (session.query(T1._date.label("max_date"))
            .order_by(T1._date.desc())
            .limit(1)
            .as_scalar()
            )

qry = session.query(MyTable).filter(MyTable._date == subquery)
results = qry.all()

输出应类似于:

# version-1
SELECT my_table.id AS my_table_id, my_table.name AS my_table_name, my_table._date AS my_table__date
FROM my_table
WHERE my_table._date = (
    SELECT max("T1"._date) AS max_date
    FROM my_table AS "T1")

# version-2
SELECT my_table.id AS my_table_id, my_table.name AS my_table_name, my_table._date AS my_table__date
FROM my_table
WHERE my_table._date = (
    SELECT "T1"._date AS max_date
    FROM my_table AS "T1"
    ORDER BY "T1"._date DESC LIMIT ? OFFSET ?
    )