2017-04-07 28 views
0

我在sqlachemy使用SQLite的请求,其通过返回该组的一个对象和一个值(平均):通过PostgreSQL中/ SQLAlchemy的选择组的第一个目的

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

但现在我需要使用PostgreSQL这是更严格的(严格的SQL),我需要做同样的事情,但它需要通过像func.avg()或其他的东西在组中的东西来替换查询(OBJ)。所以我想知道是否存在任何可以返回每个组的第一个obj的func。如果没有可能,也许我能为我的OBJ和实例调用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() 

也许实现CMPEQ在我的OBJ模型? (什么是最好的做法)

编辑:

我有一个解决方法,但我不知道这是一个很好的做法。通过第一组和下一个加盟:

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() 

我要的是组

+0

您的解决方案(通常)可能会返回多个结果。除非'min()'中的值是唯一的(我猜是这样,因为'id'听起来像是一个主键;但如果它只是一个外键,情况可能并非如此)。 - 这是[tag:most-n-per-group](其中N = 1)的特例。这里有很多SQL解决方案,但我不知道哪一个最适合[SQLAlchemy](http://stackoverflow.com/questions/tagged/sqlalchemy+greatest-n-per-group) 。 – pozs

+0

对不起,我编辑标识日期和日期是唯一索引。 – Timo

+0

但这没什么意义,因为'SELECT min(date)... GROUP BY date'和'SELECT date ... GROUP BY date'是相同的(日期中只有一个'date'无论如何,这个团队)。 - 另外,单个索引不保证其唯一性。 – pozs

回答

1

你需要列出你要选择,把他们在GROUP_BY所有列的每个组和value_avg的第一OBJ。然后,您可以选择不属于组的组成部分的聚合列。

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() 
+0

是的,但当你不得不用懒惰的查询处理像obj.obj2.obj3这样的外部对象时,这并不容易 – Timo