【发布时间】:2019-11-07 06:11:31
【问题描述】:
我有一个名为 sample_a 的 Postgres 11 表,如下所示:
time | cat | val
------+-----+-----
1 | 1 | 5
1 | 2 | 4
2 | 1 | 6
3 | 1 | 9
4 | 3 | 2
我想为每个唯一的时间步创建一个查询,在该时间步或之前获取每个类别的最新值,并通过将这些值的总和除以这些值的计数来聚合这些值。
我相信我有查询在给定的时间步长内执行此操作。例如,对于时间3,我可以运行以下查询:
select sum(val)::numeric / count(val) as result from (
select distinct on (cat) * from sample_a where time <= 3 order by cat, time desc
) x;
并获取6.5。 (这是因为在时间3,类别1 的最新是9,类别2 的最新是4。值的计数是2,它们总和为@ 987654332@,而13 / 2 是6.5。)
但是,理想情况下,我希望运行一个查询,该查询将为我提供表中每个唯一时间的所有结果。这个新查询的输出如下所示:
time | result
------+----------
1 | 4.5
2 | 5
3 | 6.5
4 | 5
如果可能,这个新查询最好避免添加另一个子选择子句;一个有效的查询将是首选。我可以通过在我的应用程序中为每个时间步运行先前的查询来获得这些先前的结果,但这对于大型sample_a 来说似乎效率不高。
这个新查询会是什么样子?
【问题讨论】:
-
我完全不明白这个要求。时间 2 的值 5 来自哪里?
-
@LaurenzAlbe 在时间 2:类别 1 的最新值为 6,类别 2 的最新值为 4。因此有两个值,6 和 4。 sum([6,4]) / count ([6,4]) = 10 / 2 = 5。
-
@LaurenzAlbe 我添加了对
3时发生的事情的解释,以便在上面的问题中清晰。 -
你提前知道所有的类别吗?
-
您可以为每个类别添加一系列如下表达式。类似的表达式可用于检测空值并获得除数的不同类别计数。不过,您可能会发现自我横向连接是一种更好的方法。
标签: sql postgresql performance distinct distinct-on