在SqlAlchemy上使用(Postgres)上的distinct的正确方法是什么?

时间:2019-07-29 11:52:08

标签: python postgresql sqlalchemy flask-sqlalchemy

我想获取具有max(timestamp)和按名称分组的表的所有列。

到目前为止,我尝试过的是: normal_query =“从表中选择max(timestamp)作为时间”

event_list = normal_query \
            .distinct(Table.name)\
            .filter_by(**filter_by_query) \
            .filter(*queries) \
            .group_by(*group_by_fields) \
            .order_by('').all()

我得到的查询:

SELECT  DISTINCT ON (schema.table.name) , max(timestamp)....

此查询基本上返回带有名称和时间戳的两列。

而我要查询:

SELECT DISTINCT ON (schema.table.name) * from table order by ....

返回该表中的所有列。这是预期的行为,我能够获取所有列,我如何在python中将其纠正以得到此语句?。基本上星号丢失了。 有人可以帮我吗?

1 个答案:

答案 0 :(得分:2)

您似乎想要的是Postgresql中的DISTINCT ON ... ORDER BY惯用法,用于选择结果( N = 1 )。因此,与其只是分组和聚合,不如

event_list = Table.query.\
    distinct(Table.name).\
    filter_by(**filter_by_query).\
    filter(*queries).\
    order_by(Table.name, Table.timestamp.desc()).\
    all()

这将最终选择按名称“分组”的,具有最大时间戳值的行。

除非您正在执行手动临时查询,否则您通常不想在应用程序代码中始终使用星号。星号基本上是“ FROM表/关系中的所有列”,如果您添加列,对其进行重新排序等等,那么稍后可能会打破您的假设。

如果您想根据时间戳在最终结果中对结果行进行排序,则可以使用例如Query.from_self()将查询转换为子查询,并在封闭的查询中进行排序:

event_list = Table.query.\
    distinct(Table.name).\
    filter_by(**filter_by_query).\
    filter(*queries).\
    order_by(Table.name, Table.timestamp.desc()).\
    from_self().\
    order_by(Table.timestamp.desc()).\
    all()