Python 在postgresql/sqlalchemy中选择group by的第一个对象

Python 在postgresql/sqlalchemy中选择group by的第一个对象,python,postgresql,sqlite,sqlalchemy,Python,Postgresql,Sqlite,Sqlalchemy,我在sqlachemy和SQLite中有一个请求,它返回group by的一个对象和一个值(平均值): 但现在我需要使用限制性更强的postgresql(严格SQL),我也需要做同样的事情,但它需要用组中的某个对象替换查询(obj),比如func.avg()或其他对象。所以我想知道是否存在能够返回每个组的第一个obj的func。如果不可能,我可以为我的obj实现comparator,例如调用func.min(obj),如下所示: result = session.query( f

我在sqlachemy和SQLite中有一个请求,它返回group by的一个对象和一个值(平均值):

但现在我需要使用限制性更强的postgresql(严格SQL),我也需要做同样的事情,但它需要用组中的某个对象替换查询(obj),比如func.avg()或其他对象。所以我想知道是否存在能够返回每个组的第一个obj的func。如果不可能,我可以为我的obj实现comparator,例如调用func.min(obj),如下所示:

result = session.query(
        func.min(obj), func.avg(obj.value).label("value_avg")
    ).group_by(
        func.date_part('second', obj.date)
    ).all()
也许在我的obj模型中实现cmpeq?(最佳做法是什么)

编辑:

我有一个解决办法,但我不确定这是一个好的做法。第一个分组人和下一个联接:

sq = session.query(
        func.min(obj.date).label("date"), func.avg(obj.value).label("value_avg")
    ).group_by(
        func.cast(func.extract('second', obj.date) / 600, Integer)
    ).order_by(obj.date).subquery()
result = session.query(obj, sq.c.value_avg).join(sq,sq.c.date == obj.date).all()

我想要的是每个组的第一个obj和组的平均值

您需要列出所有要选择的列,并将它们放入组中。然后,您可以选择不属于group by的聚合列

result = session.query(
    obj.column1,
    obj.column2,
    obj.column3,
    func.strftime('%s', obj.date),
    func.avg(obj.value).label("value_avg")
).group_by(
    obj.column1,
    obj.column2,
    obj.column3,
    obj.date
).all()

您的解决方案(通常)可能会返回多个结果。除非
min()这是的一个特例(其中N=1)。这里已经有很多SQL解决方案,但我不知道哪一个最适合。很抱歉,我编辑了Id to date,并且date是唯一的索引。但是这没有多大意义,因为
SELECT min(date)。。。按日期分组
选择日期。。。按日期分组
是相同的(无论如何,
日期
组中只有一个
日期)此外,单个索引不能保证其唯一性。是的,我同意,但在我的结果中,我可以访问我需要的其他属性。对于SQlite,我没有这个问题,因为在第一种情况下,查询(obj,func.avg(obj.value).label(“value_avg”))可以解决这个问题
如果需要同时选择聚合值和非聚合值,我可以访问obj属性为什么不使用?是的,但当您必须使用惰性查询处理外来对象(如obj.obj2.obj3)时,这并不容易
result = session.query(
    obj.column1,
    obj.column2,
    obj.column3,
    func.strftime('%s', obj.date),
    func.avg(obj.value).label("value_avg")
).group_by(
    obj.column1,
    obj.column2,
    obj.column3,
    obj.date
).all()