SQL中使用窗口函数对每个分区的last_value求和

问题描述 投票:0回答:3

我有一个表,用于存储每个实体在任何时间点使用的总磁盘空间。我想找到一段时间内使用的峰值磁盘。 例如,数据看起来像这样

注意:时间戳是精确到秒的实际时间戳,为了简洁起见,我将其设置为上午 10 点等

timestamp | entity_id | disk_used
---------------------------------
    9am   |         1 |  10
   10am   |         2 |  20
   11am   |         2 |  15
   12am   |         1 |  12
     

在此示例中,使用的最大磁盘为 30(10 个来自实体 1,20 个来自实体 2)。

我尝试过很多方法。

  1. (每个实体的最大值)之和不起作用,因为它会给出结果 20 + 12 = 32。但是在实体 1 增加其大小之前,实体 2 减小了大小,因此磁盘使用峰值为 30。
  2. 我尝试使用窗口函数来查找每个实体的last_value的总和
select timestamp, entity_id,
    disk_used, 
    sum(last_value(disk_used) over(
        partition by entity_id order by timestamp)
    ) sum_of_last

尝试生成,这样我就可以最大化它,

timestamp | entity_id | disk_used | sum_of_last
-----------------------------------------------
    9am   |         1 |  10       |   10
   10am   |         2 |  20       |   30
   11am   |         2 |  15       |   25       // (10 + 15)
   12am   |         1 |  12       |   27       // (12 + 15)
     

但是,该查询不起作用,因为我们无法聚合 ISO 标准 SQL 2003 中的窗口函数。我正在使用 Amazon timestream 数据库。查询引擎与 ISO 标准 SQL 2003 兼容。

-- 重新表述同一个问题,在每个时间戳,我们都有数据点,即该时刻使用的总磁盘数。 要查找该时刻使用的总磁盘总量,请将每个实体的最后一个值相加。

有没有有效的方法来计算这个?

sql sum time-series aggregate-functions amazon-timestream
3个回答
1
投票

我想找到一段时间内磁盘使用的峰值

您可以使用两个级别的聚合:

select max(sum_disk_used)
from (
    select time, sum(disk_used) as sum_disk_used
    from mytable
    group by time
) t

子查询计算每个时间点的总

disk_used
,然后外查询只获取峰值。

如果您的数据库支持某种

limit
子句,则可以简化:

select time, sum(disk_used) as sum_disk_used
from mytable
group by time
order by sum_disk_used limit 1

要过滤给定时间段,您通常会向子查询添加

where
子句。


0
投票

如果您只有两个实体,您可以这样做:

select t.*,
       (last_value(case when entity_id = 1 then disk_used end ignore nulls) over (order by time) +
        last_value(case when entity_id = 2 then disk_used end ignore nulls) over (order by time)
       ) as total        
from t;

将其推广到所有实体的一种方法是每次为每个实体生成一行,估算值并聚合:

select ti.time, e.entity_id,
       last_value(disk_used ignore nulls) over (partition by e.entity_id order by t.time) as imputed_disk_used
from (select distinct time from t) ti cross join
     (select distinct entity_id from t) e left join
     t
     on ti.time = t.time and e.entity_id = t.entity_id;

然后你可以聚合:

select time, sum(imputed_disk_used)
from (select ti.time, e.entity_id,
             last_value(disk_used ignore nulls) over (partition by e.entity_id order by t.time) as imputed_disk_used
      from (select distinct time from t) ti cross join
           (select distinct entity_id from t) e left join
           t
           on ti.time = t.time and e.entity_id = t.entity_id
     ) te
group by time;

但是,这会给出每次的值,而不是每次

entity_id


0
投票

选择* 从 ( 选择主键列、时间 , sum(disk_used) Over (按 EntityId 分区 按时间顺序 ) as sum_disk_used ,Last_Value(PrimaryKeyColumn) Over(按EntityId分区,按时间顺序)作为Id 来自我的表 ) t 其中 Id=PrimaryKeyColumn

© www.soinside.com 2019 - 2024. All rights reserved.