2010-03-22 2 views
1

Oracle 데이터베이스에 각 행의 삽입 타임 스탬프가로드 된 DATE 열이있는 테이블이 있습니다. .행의 타임 스탬프가 값보다 작거나 같은 경우 분석 함수를 사용하여 레코드 세트를 그룹화하십시오.

COL_1   COL_2   TS 
    A    1   Mon 15, February 2010 10:03:22 
    B    2   Mon 15, February 2010 10:05:37 
    C    3   Mon 15, February 2010 10:20:21 
    D    4   Mon 15, February 2010 10:20:21 
    E    5   Mon 15, February 2010 10:20:24 
    F    6   Mon 15, February 2010 10:23:35 
    G    7   Mon 15, February 2010 10:45:22 

내가이 같은 상관 관계를하고 싶은 5 분 사이에 관련 기록을 assumming,이 같은 데이터 있도록 나는, 일부 이벤트 사이의 상관 관계를 분석하기 위해 같은 테이블에서 기존 데이터를 사용할 필요가 현재와 ​​다음 "TS"의 최대 차이 :

FIRST_TS       COUNT 
Mon 15, February 2010 10:03:22   2 
Mon 15, February 2010 10:20:21   4 
Mon 15, February 2010 10:45:22   1 

분석 기능을 사용하여이를 구현할 수 있습니까? 방법?

+0

오라클의 버전은 무엇입니까? 분석을 사용하려면 9i 이상이어야합니다. –

답변

1

함께이 의지 그룹 이전 행에서 먼 5 분 미만되는 행 :

--ALTER SESSION SET nls_date_format= 'dy dd, month yyyy hh24:mi:ss'; 
--ALTER SESSION SET nls_date_language='ENGLISH'; 
SQL> WITH DATA AS (
    2 SELECT to_date('Mon 15, February 2010 10:03:22') ts FROM dual 
    3 UNION ALL SELECT to_date('Mon 15, February 2010 10:05:37') FROM dual 
    4 UNION ALL SELECT to_date('Mon 15, February 2010 10:20:21') FROM dual 
    5 UNION ALL SELECT to_date('Mon 15, February 2010 10:20:21') FROM dual 
    6 UNION ALL SELECT to_date('Mon 15, February 2010 10:20:24') FROM dual 
    7 UNION ALL SELECT to_date('Mon 15, February 2010 10:23:35') FROM dual 
    8 UNION ALL SELECT to_date('Mon 15, February 2010 10:45:22') FROM dual 
    9 ) 
10 SELECT MIN(ts) first_ts, COUNT(*) COUNT 
11 FROM (SELECT ts, SUM(gap) over(ORDER BY ts) ts_group 
12    FROM (SELECT ts, 
13       CASE 
14        WHEN ts - lag(ts) over(ORDER BY ts) 
15         <= 5/(60 * 24) THEN 
16        0 
17        ELSE 
18        1 
19       END gap 
20      FROM DATA)) 
21 GROUP BY ts_group; 

FIRST_TS        COUNT 
-------------------------------- ---------- 
mon 15, february 2010 10:03:22   2 
mon 15, february 2010 10:20:21   4 
mon 15, february 2010 10:45:22   1 
+0

뛰어난! 고마워요! –

0

당신이에 대한 분석이 필요하다고 생각하지 않는다, 당신은 그냥 오분 간격을 생성해야합니다. 다음 코드는 공통 테이블 식 (AKA 하위 쿼리 인수 분해)을 사용하여 지정된 시작 날짜에서 5 분 간격을 생성합니다. 주요 쿼리 간격 여기

내에 레코드 수를 생산하기 위해 SUM() 및 CASE()를 사용하면 테스트 데이터입니다 :

SQL> select * from t23 
    2/

C  COL2 COL3 
- ---------- ----------------- 
A   1 15-feb-2010 10:03 
B   2 15-feb-2010 10:05 
C   3 15-feb-2010 10:20 
D   4 15-feb-2010 10:20 
E   5 15-feb-2010 10:20 
F   6 15-feb-2010 10:23 
G   7 15-feb-2010 10:45 

7 rows selected. 

SQL> 

그리고 여기 결과

SQL> with t_range as (
    2  select to_date('15 February 2010 10:00','DD Month YYYY hh24:mi') 
    3            + ((level-1)/288) as this_5mins 
    4    , to_date('15 February 2010 10:00','DD Month YYYY hh24:mi') 
    5            + (level/288) as next_5mins 
    6  from dual 
    7  connect by level <= 12 
    8  ) 
    9 select t_range.this_5mins 
10   , sum(case when t23.col3 >= t_range.this_5mins 
11     and t23.col3 < t_range.next_5mins 
12     then 1 
13     else 0 end) as cnt 
14 from t23 cross join t_range 
15 group by t_range.this_5mins 
16/

THIS_5MINS    CNT 
----------------- ---------- 
15-feb-2010 10:10   0 
15-feb-2010 10:20   4 
15-feb-2010 10:30   0 
15-feb-2010 10:05   1 
15-feb-2010 10:55   0 
15-feb-2010 10:15   0 
15-feb-2010 10:40   0 
15-feb-2010 10:45   1 
15-feb-2010 10:00   1 
15-feb-2010 10:35   0 
15-feb-2010 10:25   0 
15-feb-2010 10:50   0 

12 rows selected. 

SQL> 
0
에게 있습니다

다음은 분석 함수가있는 버전입니다. 테이블을 데이터로 테이블을 생성하는 유니온 서브 쿼리로 대체하십시오.

select distinct 
    first_value(ts) over (partition by continuous_group order by ts) first_ts 
    , count(ts) over (partition by continuous_group) count 
from (
    select col_1, col_2, ts, sum(discontinuity) over (order by ts) continuous_group 
    from (
    select col_1, col_2, ts, case when lag(ts) over (order by ts) + numtodsinterval(5,'MINUTE') <= ts then 1 else 0 end discontinuity 
    from (
    select 'A' col_1, 1 col_2, to_date('2010-2-15 10:03:22', 'YYYY-MM-DD HH24:MI:SS') ts from dual 
    union (
    select 'B' col_1, 2 col_2, to_date('2010-2-15 10:05:37', 'YYYY-MM-DD HH24:MI:SS') ts from dual) 
    union (
    select 'C' col_1, 3 col_2, to_date('2010-2-15 10:20:21', 'YYYY-MM-DD HH24:MI:SS') ts from dual) 
    union (
    select 'D' col_1, 4 col_2, to_date('2010-2-15 10:20:21', 'YYYY-MM-DD HH24:MI:SS') ts from dual) 
    union (
    select 'E' col_1, 5 col_2, to_date('2010-2-15 10:20:24', 'YYYY-MM-DD HH24:MI:SS') ts from dual) 
    union (
    select 'F' col_1, 6 col_2, to_date('2010-2-15 10:23:35', 'YYYY-MM-DD HH24:MI:SS') ts from dual) 
    union (
    select 'G' col_1, 7 col_2, to_date('2010-2-15 10:45:22', 'YYYY-MM-DD HH24:MI:SS') ts from dual) 
)) 
) order by first_value(ts) over (partition by continuous_group order by ts); 
관련 문제