【发布时间】:2017-09-02 11:18:33
【问题描述】:
我在 sqlachemy 中有一个使用 SQLite 的请求,它返回 group by 的一个对象和一个值(avg):
result = session.query(
obj, func.avg(obj.value).label("value_avg")
).group_by(
func.strftime('%s', obj.date)
).all()
但现在我需要使用限制性更强的 postgresql(严格的 SQL),我需要做同样的事情,但它需要用 func.avg() 之类的组中的某些东西替换 query(obj) 或其他东西.所以我想知道是否存在任何能够返回每个组的第一个 obj 的函数。如果不可能,也许我可以为我的 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()
也许在我的 obj 模型中实现 cmp 和 eq ? (最佳做法是什么)
编辑:
我有一个解决方法,但我不确定这是一个好习惯。第一个分组和下一个加入:
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 和组的 value_avg
【问题讨论】:
-
您的解决方案(通常)可能会返回多个结果。除非
min()中的值是唯一的(我猜它是唯一的,因为id听起来像一个主键;但如果它只是一个外键,那可能不是这种情况)。 -- 这是greatest-n-per-group 的特例(其中N=1)。 SO上已经有很多SQL解决方案了,但我不知道哪个最适合SQLAlchemy。 -
对不起,我将 ID 编辑为日期,而日期是唯一的索引。
-
但这没有多大意义,因为
SELECT min(date) ... GROUP BY date和SELECT date ... GROUP BY date是相同的(无论如何date组中只有一个date)。 -- 另外,单个索引并不能保证其唯一性。 -
是的,我同意,但在我的结果中,我可以访问我需要的其他属性。使用 SQlite 我没有这个问题,因为在第一种情况下你可以这样做,因为
query(obj, func.avg(obj.value).label("value_avg"))让我可以访问 obj 属性 -
如果您需要同时选择聚合值和非聚合值,为什么不使用over()?
标签: python postgresql sqlite sqlalchemy