簡體   English   中英

在 oracle 中的 over 語句中限制數據

[英]limit data within an over statement in oracle

我想在時間戳上聚合一列。

這里有一個例子:

表包含 col1、col2、...、col_ts(時間戳列)等列。

SELECT
SUM(col1) OVER (ORDER BY col_ts ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) SUM1,
SUM(col2) OVER (ORDER BY col_ts ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) SUM2
FROM ...

現在,當時間戳之間的差異 <= 5 分鍾時,我只想要 2 PRECEDING 和 2 FOLLOWING ROWS SUMMED。

例如,讓我們看看這些時間戳值:

14.09.15 15:44:00
14.09.15 15:50:00
14.09.15 15:51:00
14.09.15 15:52:00
14.09.15 15:53:00

當在時間戳值為“14.09.15 15:51:00”的行中時,我希望 SUM 超過從 15:50 到 15:53 的值,因為 15:50 和 15:44 之間的差異更大超過 5 分鍾。

有沒有辦法在over子句中寫出這樣的條件?

或者有沒有人對此有一個好的和高性能的解決方案?

好的,我在這里看到了問題。 謝謝弗洛林。 那么一些預處理呢? 我可以找到解決方案,但我不確定是否有更快的解決方案:

select col_ts, 
       n, 
       SUM(n) OVER (ORDER BY col_ts ROWS BETWEEN LEFT_VALUE PRECEDING AND RIGHT_VALUE FOLLOWING) MY_SUM,
       SUM(n) OVER (ORDER BY col_ts RANGE BETWEEN interval '5' second PRECEDING AND interval '5' second FOLLOWING) OLD_SUM
from (
       select col_ts,
              n,
              CASE
              WHEN (LEAD(col_ts,1) OVER (ORDER BY col_ts ) - col_ts) <= INTERVAL '5' second 
              THEN 
                   CASE
                   WHEN (LEAD(col_ts,2) OVER (ORDER BY col_ts ) - LEAD(col_ts,1) OVER (ORDER BY col_ts )) <= INTERVAL '5' second 
                   THEN 2 
                   ELSE 1
                   END
             ELSE 0
             END AS RIGHT_VALUE,
             CASE 
             WHEN (col_ts - LAG(col_ts,1) OVER (ORDER BY col_ts ) ) <= INTERVAL '5' second 
             THEN 
                  CASE 
                  WHEN (LAG(col_ts,1) OVER (ORDER BY col_ts ) - LAG(col_ts,2) OVER (ORDER BY col_ts )) <= INTERVAL '5' second 
                  THEN 2 
                  ELSE 1
                  END
            ELSE 0
            END AS LEFT_VALUE
      from fg_test
  );

結果:

COL_TS                           N   MY_SUM      OLD_SUM
---------------------------  -----  -------  -----------
15.09.15 09:34:24,069000000      1        6            6
15.09.15 09:34:28,000000000      2       10           15
15.09.15 09:34:29,000000000      3       15           15
15.09.15 09:34:30,000000000      4       14           14
15.09.15 09:34:31,000000000      5       12           14
15.09.15 09:34:37,000000000      6        6            6

你怎么看?

我認為這對sql來說太多了。 您可以限制窗口中的數量或元素,您可以以某種方式限制(見下文)值,但不能同時限制兩者。

drop table fg_test;
create table fg_test(col_ts timestamp, n number);

insert into fg_test values (systimestamp, 1);
insert into fg_test values (systimestamp+4/1440/60, 2);
insert into fg_test values (systimestamp+5/1440/60, 3);
insert into fg_test values (systimestamp+6/1440/60, 4);
insert into fg_test values (systimestamp+7/1440/60, 5);
insert into fg_test values (systimestamp+13/1440/60, 6);

select col_ts, n, 
  SUM(n) OVER (ORDER BY col_ts ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) SUM1,
  SUM(n) OVER (ORDER BY col_ts RANGE BETWEEN current row AND interval '5' second FOLLOWING) SUMNEW
from fg_test;

結果:

COL_TS                                   N       SUM1       SUM2
------------------------------- ---------- ---------- ----------
14-SEP-15 06.16.28.825395000 PM          1          3          3 
14-SEP-15 06.16.33.000000000 PM          2          6         14 
14-SEP-15 06.16.34.000000000 PM          3          9         12 
14-SEP-15 06.16.35.000000000 PM          4         12          9 
14-SEP-15 06.16.36.000000000 PM          5         15          5 
14-SEP-15 06.16.42.000000000 PM          6         11          6 

(對不起,沒有像你的問題那樣采取確切的例子)

另一種方法是編寫一些 PL/SQL(打開一個游標並做一些處理)。

暫無
暫無

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

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