0

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

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

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

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

我尝试了多种方法。

  1. Sum of (max of each entity) 不起作用,因为它会给出结果 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 db。查询引擎与 ISO 标准 SQL 2003 兼容。

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

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

4

2 回答 2

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

于 2020-11-17T01:43:45.123 回答
0

我想查找某个时间段内使用的峰值磁盘

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

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在子查询中添加一个子句。

于 2020-11-17T01:43:49.823 回答