从表格的“最后”N行中获取平均值

8

在我的Postgres数据库表中,我可以按日期顺序找到cap_cs137的最后20个条目:

select cap_cs137 FROM capintec ORDER BY cap_date DESC LIMIT 20;

我也可以得到平均值:
select avg(cap_cs137) FROM capintec LIMIT 20;

然而,我如何将上述语句组合起来以按日期顺序获取最后20个条目的平均值?

我们有一个过时的RHEL 5.8服务器,支持Postgres 8.1.23,因此不允许使用WITH查询。

2个回答

10

您可以使用公共表表达式(CTE):

WITH s AS
    (SELECT cap_cs137 FROM capintec ORDER BY cap_date DESC LIMIT 20)
SELECT avg(cap_cs137) FROM s;

第一个查询会被缓存为一个临时表“s”,然后我们在最终的查询中对其进行聚合。

编辑:

结果证明,由于使用的是较旧版本的Postgres,OP无法使用CTE,因此最终答案是一个子查询(在可读性方面我个人更喜欢CTE;但在这种情况下两种方法完全相同)。

SELECT avg(cap_cs137) FROM
   (SELECT cap_cs137 FROM capintec ORDER BY cap_date DESC LIMIT 20);

谢谢您提供的解决方案。不幸的是,我们的服务器已经过时,使用的是postgresql 8.1.23版本,因此我无法使用WITH命令。 - moadeep
然后,gurka建议的内部选择应该可以工作。如果我没记错,在CTE之外运行子查询的聚合函数会有一些奇怪的规则(还是在子查询中运行聚合函数查询?),所以可能因情况而异:SELECT avg(cap_cs137) FROM (SELECT cap_cs137 FROM capintec ORDER BY cap_date DESC LIMIT 20); - zxq9
在这种情况下,CTE 没有用处。只需使用子查询即可。 - Erwin Brandstetter
1
假设表上有一个属性“group”,使用WHERE来限制子查询到给定的组。例如,要对“超级朋友”从some_table中最新的20个条目的“stuff”进行平均值计算:SELECT avg(stuff) FROM (SELECT stuff FROM some_table WHERE group = "Super Friends" ORDER BY date DESC LIMIT 20); - zxq9
1
在这种情况下,您将得到混合在一起的结果。但是,如果您将此查询作为子查询进行,在新表的每一行中执行该查询,您可以创建一个三阶段查询,返回所有组的“{Group,RunningAverage}”列表。 - zxq9
显示剩余6条评论

4

只需使用内部选择:

SELECT AVG(cap_cs137)
FROM (SELECT cap_cs137 FROM capintec ORDER BY cap_date DESC LIMIT 20) AS sub;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接