簡體   English   中英

帶窗口函數的 SQL 中每個分區的 last_value 總和

[英]Sum of last_value of each partition in SQL with window functions

我有一個表,用於存儲每個實體在任何時間點使用的總磁盤。 我想找到某個時間段內使用的峰值磁盤。 例如,數據看起來像

注意:時間戳是具有秒精度的實際時間戳,為簡潔起見,我將其設置為 10am 等

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 兼容。

-- 重新表述相同的問題,在每個時間戳,我們都有數據點,用於該時刻使用的總磁盤。 要找到當時使用的總磁盤總數,請對每個實體的最后一個值求和。

有沒有一種有效的方法來計算這個?

如果您只有兩個實體,您可以執行以下操作:

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

我想找到某個時間段內使用的峰值磁盤

您可以使用兩個級別的聚合:

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子句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM