Meh*_*dad 7 python sqlalchemy row-number
如何在以下查询中过滤row_number == 1:
query = session.query(Foo, func.row_number().over(
partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label("row_number"))
query = query.filter(Foo.time_key <= time_key)
# query = query.filter(row_number == 1)
result = query.all()
Run Code Online (Sandbox Code Playgroud)
Meh*_*dad 21
我找到了:
row_number_column = func.row_number().over(partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label('row_number')
query = self.session.query(Foo)
query = query.filter(Foo.time_key <= time_key)
query = query.add_column(row_number_column)
query = query.from_self().filter(row_number_column == 1)
Run Code Online (Sandbox Code Playgroud)
也可以使用子查询来完成:
sub_query = session.query(
Foo,
func.row_number().over(partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label("row_number")
)
sub_query = sub_query.filter(Foo.time_key <= time_key).subquery()
query = session.query(sub_query).filter(sub_query.c.row_number == 1)
Run Code Online (Sandbox Code Playgroud)
它基本上生成一个等效的 SQL 语句,将 row_number 添加为列。
编译声明。
sub_query = session.query(
Foo,
func.row_number().over(partition_by=Foo.foo_field, order_by=desc(Foo.foo_date_time)).label("row_number")
)
sub_query = sub_query.filter(Foo.time_key <= time_key).subquery()
query = session.query(sub_query).filter(sub_query.c.row_number == 1)
str(query.statement.compile())
Run Code Online (Sandbox Code Playgroud)
将生成以下内容:
-- SubQuery function
SELECT anon_1.time_key,
anon_1.foo_field,
anon_1.foo_date_time,
anon_1.row_number
FROM (
SELECT foo.time_key AS time_key,
foo.foo_field AS foo_field,
foo.foo_date_time AS foo_date_time,
row_number() OVER (PARTITION BY foo.foo_field ORDER BY foo.foo_date_time DESC) AS row_number
FROM foo
WHERE foo.time_key <= %(time_key_1)s
) AS anon_1
WHERE anon_1.row_number = %(row_number_1)s
Run Code Online (Sandbox Code Playgroud)
更新:请记住,自 SQLAlchemy 1.4 起, Query.from_self方法已被弃用,根据官方文档,该方法将在 2.0 中删除
如果有人使用它,您可以查看此案例的迁移指南