2016-06-19 32 views
1

我有帶時間戳記列的表tmstmp,該表包含某些事件的日誌。我需要找出在1分鐘內發生的最大數量事件。如何在Oracle中選擇最密集的1分鐘

請仔細閱讀!我要提取的時間戳極小部分,總結如下:

select count(*), TO_CHAR(tmstmp,'MI') 
    from log_table 
    group by TO_CHAR(tmstmp,'MI') 
    order by TO_CHAR(tmstmp,'MI'); 

它需要花費1日的記錄,然後向前看直到其選擇從1號和金額數在1分鐘內的所有記錄記錄,然後採取第二,做同樣的等等。

而作爲結果必須有(總和,開始時間戳)的記錄集。

任何人都有一段代碼的地方,並小心分享嗎?

+0

有你已經選中了這個問題? http://stackoverflow.com/questions/14989927/sql-sliding-window-finding-max-value-over-interval我想它也可以適應1分鐘的時間間隔。 –

回答

5

與一個邏輯窗口分析功能可以直接提供這樣的信息:

select l.tmstmp, 
count(*) over (order by tmstmp range between current row and interval '59.999999' second following) cnt 
from log_table l 
order by 1 
; 

TMSTMP        CNT 
--------------------------- ---------- 
01.01.16 00:00:00,000000000   4 
01.01.16 00:00:10,000000000   4 
01.01.16 00:00:15,000000000   3 
01.01.16 00:00:20,000000000   2 
01.01.16 00:01:00,000000000   3 
01.01.16 00:01:40,000000000   2 
01.01.16 00:01:50,000000000   1 

請調整您的精度的區間長度。它必須是低於1分鐘的最高可能值。

爲了獲得最大分鐘使用子查詢(不要忘記,你可能會收到更多的一個記錄 - 用MAX計數):

with tst as (
select l.tmstmp, 
count(*) over (order by tmstmp range between current row and interval '59.999999' second following) cnt 
from log_table l) 
select * from tst where cnt = (select max(cnt) from tst); 

TMSTMP        CNT 
--------------------------- ---------- 
01.01.16 00:00:00,000000000   4 
01.01.16 00:00:10,000000000   4 
+0

儘管@CarloCe提供了有趣的解決方案並且速度很快,但是該解決方案在我們的產品數據庫雲服務器上運行速度提高了20倍。 –

2

一種方法使用join和聚集:

select t.* 
from (select l.tmstmp, count(*) 
     from log_table l join 
      log_table l2 
      on l2.tmstmp >= l.tmstmp and 
       l2.tmstmp < l.tmstmp + interval '1' minute 
     group by l.tmpstmp 
     order by count(*) desc 
    ) t 
where rownum = 1; 

注:這是假定tmstmp在每行都是唯一的。如果這不是真的,那麼子查詢應該是聚合的一些列,唯一。

編輯:

對於大數據,有可能利用累計和更有效的方式:

select tmstamp - interval 1 minute as starttm, tmstamp as endtm, cumulative 
from (select tmstamp, sum(inc) over (order by tmstamp) as cumulative 
     from (select tmstamp, 1 as inc from log_table union all 
      select tmstamp + interval '1' day, -1 as inc from log_table 
      ) t 
     order by sum(inc) over (order by tmstamp) desc 
    ) t 
where rownum = 1; 
+0

謝謝。非常徹底的答案..雖然沒有工作..你錯過了間隔帕拉姆+間隔'1''的拳頭..拳頭SQL永遠在60K記錄..我正在看它atm ..第二個返回1記錄只有 –

2

我覺得你可以在SELECT語句中使用子查詢實現自己的目標,爲後續:

SELECT tmstmp, (
    SELECT COUNT(*) 
    FROM log_table t2 
    WHERE t2.tmstmp >= t.tmstmp AND t2.tmstmp < t.tmstmp + 1/(24*60) 
) AS events 
FROM log_table t; 
+0

它很難測試,但它的工作原理。它運作得很快! –

相關問題