[英]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.