효율적인 Query 방법 문의 드립니다. 0 9 1,831

by lego [SQL Query] 쿼리 [2014.05.13 11:32:08]


안녕하세요.

효율적인 쿼리 방법 문의 드립니다.

1일 단위 Table에  2초간격으로  몇건의 데이터 이용 이렇게  데이터 적제가 됩니다. 총 43000 건 정도입니다.

ex) 1일 단위 Table

unixtime             cnt

1399734012        4

1399734014        1

1399734016        3

1399734018        3

1399734020        2

.......

1399734042      1

1399734044      1

1399734046      3

1399734048       3

1399734050       2

제가 추출하고자 하는 것은 오늘 하루 중 10초 동안의 가장 peak 건수 를 뽑아 내는 쿼리 입니다.

위 두 time 을 예로 들면

첫번째 10초간 평균 2.6

.....

두번째 10초간 평균 2

결과

하루중 10초동안의 최고값  2.6 이 표시되어야 합니다.

 

전체 쿼리 후 로직에서 비교하면서 처리 하려고 했지만  한번에 쿼리로 도출 할 수 있을 거 같아 문의 드립니다.

43000 건 중 10초 간으로 그룹핑 하면 4300 건 중 MAX로 구하면 될 거 같은데

10초간으로 그룹핑 하는것을 어떻게 처리 하면 좋을지 감이 안잡혀서요.

어떻게 하면 좋을 거 같다라고 간략한 조언을 해주시면 진심으로 감사드립니다.

 

감사합니다

regard.

 

by 농부지기 [2014.05.13 12:03:11]

님께서 unixtime 의  값을 보면   초 앞의 값이 어떤 값인지 모르겠네요.

일자 맞나요?

 

일단, 답변을 일자'20140513' 기준으로 만들었어요.

WITH TT(UT, CNT) AS
   ( SELECT '20140513 0002', 2 FROM DUAL UNION ALL
     SELECT '20140513 0004', 3 FROM DUAL UNION ALL
     SELECT '20140513 0006', 7 FROM DUAL UNION ALL
     SELECT '20140513 0008', 1 FROM DUAL UNION ALL
     SELECT '20140513 0010', 3 FROM DUAL UNION ALL
     SELECT '20140513 0012', 6 FROM DUAL UNION ALL
     SELECT '20140513 0014', 8 FROM DUAL UNION ALL
     SELECT '20140513 0016', 0 FROM DUAL UNION ALL
     SELECT '20140513 0018', 1 FROM DUAL 
   )
--2. 10초별 합계 및 순위 구하기
SELECT RG.SDT
     , RG.EDT
     , SUM(TT.CNT)
     , ROW_NUMBER() OVER(ORDER BY SUM(TT.CNT) DESC)  AS RK
  FROM TT
     , (--1. 일자별 10초 간격 구하기
        SELECT TO_CHAR(SYSDATE, 'YYYYMMDD') || ' ' || LPAD( (ROWNUM - 1) * 10, 4, '0') AS SDT
             , TO_CHAR(SYSDATE, 'YYYYMMDD') || ' ' || LPAD( (ROWNUM * 10)    , 4, '0') AS EDT
          FROM DUAL
        CONNECT BY LEVEL <= 6
       ) RG
 WHERE TT.UT BETWEEN RG.SDT AND RG.EDT
 GROUP BY RG.SDT, RG.EDT ;

 


by lego [2014.05.13 13:45:29]

조언 감사드립니다.

unixtime 은 unix 서버의 record timestamp 입니다.  unixtime 형식의 integer 값입니다.

바쁘신 와중에 조언 해주셔 감사합니다.

감사합니다.

regard.


by 유령회원 [2014.05.13 12:22:12]

window절을 이용하면 쉽게 될수도 있을꺼 같습니다. 내가 이해하고 있는게 맞다면..

avg(cnt)로 주고 범위를 unixtime 10초간으로 설정하면 10초간의 평균 cnt가 나옵니다


by 농부지기 [2014.05.13 13:07:22]

windows절도 가능한가요?  windows절을 이용한 sql 문은 한번도 안해 봤네요.

저도 궁금하네요.

windows절을 이용한 sql문 작성가능할까요?


by lego [2014.05.13 13:52:39]

조언 해주셔서 감사합니다.

집계함수, 순위함수 등을 windows function이라고 부르는군요.

부족한 상태에서 새로운 것을 배웠습니다.

감사합니다.


by 마농 [2014.05.13 14:20:06]

집계함수는 집계 결과만 딸랑 보여주는 것이고
분석함수는 집계 결과도 함께 보여주는 것이죠
지금 집계결과만 필요하므로, 굳이 분석함수를 사용할 필요는 없겠죠.
분석함수에 대해 좀 더 알고자 한다면 다음 자료 참고해 보세요.
http://www.gurubee.net/article/61235


by 마농 [2014.05.13 13:09:00]
-- 10 초의 구간이 딱 2,4,6,8,10 으로 정해진게 아니라면?
-- 저는 0,2,4,6,8 로 하시길 권해드리고 싶네요.
-- 이 기준이 좀더 명확하리라 셍각이 들고요, 실제로 쿼리 작성시에도 더 깔끔합니다.
SELECT *
  FROM (SELECT TRUNC(unixtime, -1) unixtime
             , AVG(cnt) avg_cnt
          FROM t
         GROUP BY TRUNC(unixtime, -1)
         ORDER BY avg_cnt DESC
        )
 WHERE ROWNUM = 1
;

 


by lego [2014.05.13 13:43:26]

와우~ 정말 감사합니다.

완전 심플하게 처리 되네요.

진심으로 드립니다.

조언만 부탁드렸는데 Sample 까지 진심으로 감사드립니다.

완전 스승님으로 모시고 싶습니다.

감사합니다.

regard.


by 농부지기 [2014.05.14 09:16:02]

10초 단위를 trunc해서 처리 했네요.

정말 초간단이네요.

역쉬 마농님

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입