【问题标题】:Running "distinct on" across all unique thresholds in a postgres table在 postgres 表中的所有唯一阈值上运行“distinct on”
【发布时间】: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 / 26.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


【解决方案1】:

看看这种方式的性能是否可以接受。语法可能需要微调:

select t.time, avg(mr.val) as result
from (select distinct time from sample_a) t,
    lateral (
        select distinct on (cat) val
        from sample_a a
        where a.time <= t.time
        order by a.cat, a.time desc
    ) mr
group by t.time

【讨论】:

  • 聪明的解决方案!但它需要一些错误更正:dbfiddle.uk/…
  • 谢谢@S-Man postgres 不是我的本地平台,我正在使用手机。
【解决方案2】:

我认为您只需要累积函数:

select time,
       sum(sum(val)) over (order by time) / sum(sum(num_val)) over (order by time) as result
from (select time, sum(val) as sum_val, count(*) as num_val
      from sample_a a
      group by time
     ) a;

请注意,如果val 是整数,您可能需要转换为数字才能获得小数值。

这也可以不用子查询来表达:

select time,
       sum(sum(val)) over (order by time) / sum(count(*)) over (order by time) as result
from sample_a
group by time

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    相关资源
    最近更新 更多