2013-03-14 86 views
1

我有一個由logtime/value1,value2 ...元組以及其他列(如測量點標識)組成的Oracle表。這些值是不同計數器的採樣值,每個計數器單調遞增,即較新的值不能小於較舊的值。但是,對於多個採樣,值可以保持相等,並且值有時可能會丟失,因此相應的表條目爲NULL,而同一個logtime的其他值有效。而且,日誌時間間隔不是恆定的。計算具有重複值和缺失值的時間序列中的增量

在下面,爲簡單起見,我將只考慮日誌時間和一個計數器值。

我必須計算從每個日誌時間到前一個日誌時間的增量。使用另一個問題here中描述的方法爲每個NULL值提供了兩個NULL增量,因爲兩個減法無效。當連續值相同時,第二個解決方案失敗,因爲與前一個值的差值被計算兩次。

另一種解決方案是構造一個派生表/視圖,並將這些NULL值替換爲最新的舊有效值。我的方法是這樣的:

SELECT A.logtime, A.val, 
(A.val - (SELECT MAX(C.val) 
      FROM tab C 
      WHERE logtime = 
      (SELECT MAX(B.logtime) 
       FROM tab B 
       WHERE B.logtime < A.logtime AND B.val IS NOT NULL))) AS delta 
FROM tab A; 

我懷疑,這將導致非常低效的查詢,爲表中的所有N個計數器,這將導致(1 + 2 * N)選擇這樣做時尤其如此。它也沒有從櫃檯單調增加的事實中獲益。

有沒有其他方法?我認爲其他人也有類似的問題。

一個顯而易見的解決方案當然是填充構造新表的NULL值或修改現有表,但不幸的是,在這種情況下這是不可能的。在進入時避免/消除它們也是不可能的。

任何幫助將不勝感激。

+0

如果通過櫃檯按時間和次序命令他們,那麼你可以用戶http://www.oracle-base.com/articles/misc/lag-lead -analytic-functions.php#lag – Sibster 2013-03-14 12:38:30

回答

2
select 
    logtime, 
    val, 
    last_value(val ignore nulls) over (order by logtime) 
     as not_null_val, 
    last_value(val ignore nulls) over (order by logtime) - 
     last_value(val ignore nulls) over (order by logtime rows between unbounded preceding and 1 preceding) 
     as delta 
from your_tab order by logtime; 
+0

我發現了一種避免使用Oracle SQL內置LAG函數的嵌套SELECT語句的方法: SELECT logtime,val, NVL(val-LAG(val IGNORE NULLS)OVER(ORDER BY日誌時間),0)AS增量 FROM標籤; 似乎按照我的意圖工作。 – Stefan 2013-03-14 12:51:15

+0

@stefan - 然後在這裏發佈您的解決方案。 (你可以回答你自己的問題)。 – APC 2013-03-14 12:53:02

+0

@Stefan - 你自己的解決方案比我的更好。 – 2013-03-14 13:08:50

1

我找到了一種方法來避免使用Oracle SQL的內置的LAG函數嵌套的SELECT語句:

SELECT logtime, val, 
     NVL(val-LAG(val IGNORE NULLS) OVER (ORDER BY logtime), 0) AS delta 
FROM tab; 

似乎工作,我打算。

(這裏重複作爲一個單獨的答案)

相關問題