[퀴즈] 기준시간내에 재등록된 데이터 검색 0 10 2,610

by 마농 [2009.04.22 17:53:40]


[퀴즈] 기준시간내에 재등록된 데이터 검색

마농군와 호야군은 지뢰찾기를 합니다.
지뢰찾기에 성공할때마다 성공한 시각을 기록하였습니다.

WITH mine AS
(
SELECT '마농' nm, '20090422090000' sdt FROM dual
UNION ALL SELECT '마농', '20090422091005' FROM dual
UNION ALL SELECT '마농', '20090422091502' FROM dual
UNION ALL SELECT '마농', '20090422091730' FROM dual
UNION ALL SELECT '마농', '20090422094000' FROM dual
UNION ALL SELECT '마농', '20090422095000' FROM dual
UNION ALL SELECT '호야', '20090422190000' FROM dual
UNION ALL SELECT '호야', '20090422191005' FROM dual
UNION ALL SELECT '호야', '20090422191502' FROM dual
UNION ALL SELECT '호야', '20090422193730' FROM dual
UNION ALL SELECT '호야', '20090422194000' FROM dual
UNION ALL SELECT '호야', '20090422195000' FROM dual
)
SELECT * FROM mine

[문제] 이 자료로 부터 성공후 5분안에 다시 성공한 자료를 뽑고자 합니다.
      (전체 자료중 색칠한 부분에 해당되는 자료를 뽑으시면 됩니다.)

NM

SDT

마농

20090422090000

마농

20090422091005

마농

20090422091502

마농

20090422091730

마농

20090422094000

마농

20090422095000

호야

20090422190000

호야

20090422191005

호야

20090422191502

호야

20090422193730

호야

20090422194000

호야

20090422195000


[답안보기] <== 트리플클릭
SELECT nm, sdt
  FROM (SELECT t.*
             , COUNT(*) OVER(PARTITION BY nm
                                 ORDER BY TO_DATE(sdt,'yyyymmddhh24miss')
                         RANGE BETWEEN NUMTODSINTERVAL(5,'minute') PRECEDING
                                   AND NUMTODSINTERVAL(5,'minute') FOLLOWING
                             ) AS cnt
          FROM mine t
        )
 WHERE cnt > 1
;

by Ejql [2009.04.23 09:38:43]
풀어보고 있는중인데요. 문제가 성공후 5분안에 다시 성공한 자료를 뽑는다라고 하셨는데요. 색칠한 부분중에 20090422091005, 20090422191005,20090422193730
이 3개는 답이 안나와야될것 같은데요.

by Ejql [2009.04.23 09:40:13]
제 한계를 느끼면서 여기저기 조합해서 풀어봤습니다.

select c.*
from
(
select b.*, TO_TIMESTAMP(lag(sdt,1) over(partition by chk order by sdt), 'YYYY-MM-DD HH24-MI-SS') flag_b
from (
SELECT 1 chk, a.*, row_number() over(ORDER BY sdt) rr, TO_TIMESTAMP(sdt,'YYYY-MM-DD HH24-MI-SS') flag_a FROM mine a) b
) c
where flag_a - flag_b <= TO_DSINTERVAL('0 00:05:00');

by 김강환 [2009.04.23 10:33:40]
SELECT NM,DECODE(LV,1,PREV_SDT,2,SDT)
FROM(
SELECT NM
,SDT
,LAG(SDT,1) OVER(PARTITION BY NM ORDER BY SDT ASC) PREV_SDT
,TO_NUMBER(TO_CHAR(TO_DATE((TO_DATE(SDT,'YYYYMMDD HH24:MI:SS')
-TO_DATE(LAG(SDT,1) OVER(PARTITION BY NM ORDER BY SDT ASC),'YYYYMMDD HH24:MI:SS'))*86400,'SSSSS'),'HH24MISS')) GAP
FROM MINE
) A,(SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL<=2)
WHERE GAP<=500
GROUP BY NM,DECODE(LV,1,PREV_SDT,2,SDT)

by ???? [2009.04.23 10:56:05]
+_+;; ㅋㅋ 요래 풀어봐도 될란가요 ㅋ;

WITH mine AS
(
SELECT '마농' nm, '20090422090000' sdt FROM dual
UNION ALL SELECT '마농', '20090422091005' FROM dual
UNION ALL SELECT '마농', '20090422091502' FROM dual
UNION ALL SELECT '마농', '20090422091730' FROM dual
UNION ALL SELECT '마농', '20090422094000' FROM dual
UNION ALL SELECT '마농', '20090422095000' FROM dual
UNION ALL SELECT '호야', '20090422190000' FROM dual
UNION ALL SELECT '호야', '20090422191005' FROM dual
UNION ALL SELECT '호야', '20090422191502' FROM dual
UNION ALL SELECT '호야', '20090422193730' FROM dual
UNION ALL SELECT '호야', '20090422194000' FROM dual
UNION ALL SELECT '호야', '20090422195000' FROM dual
)
Select T1.*
From (
Select NM, SDT, sdt-lag(SDT) over(partition by NM order by SDT ) lag1, lead(SDT) over(partition by NM order by SDT )-sdt lead1
From mine
) T1
Where lag1 <= 500
or lead1 <= 500
;

by 서성우 [2009.04.23 10:58:47]
WITH mine AS
(
SELECT '마농' nm, '20090422090000' sdt FROM dual
UNION ALL SELECT '마농', '20090422091005' FROM dual
UNION ALL SELECT '마농', '20090422091502' FROM dual
UNION ALL SELECT '마농', '20090422091730' FROM dual
UNION ALL SELECT '마농', '20090422094000' FROM dual
UNION ALL SELECT '마농', '20090422095000' FROM dual
UNION ALL SELECT '호야', '20090422190000' FROM dual
UNION ALL SELECT '호야', '20090422191005' FROM dual
UNION ALL SELECT '호야', '20090422191502' FROM dual
UNION ALL SELECT '호야', '20090422193730' FROM dual
UNION ALL SELECT '호야', '20090422194000' FROM dual
UNION ALL SELECT '호야', '20090422195000' FROM dual
)
SELECT * FROM
(SELECT nm,
sdt,
Ceil((To_Char(To_Date(sdt),'sssss') - Decode(a,0,0,To_Char(To_Date(a),'sssss')))/60) a,
Ceil((Decode(b,0,0,To_Char(To_Date(b),'sssss')) - To_Char(To_Date(sdt),'sssss'))/60) b
FROM
(SELECT nm
,sdt
,Nvl(Lag(sdt) over(PARTITION BY nm ORDER BY rownum),0) a
,Nvl(Lead(sdt) over(PARTITION BY nm ORDER BY ROWNUM),0) b
FROM mine))
WHERE (a BETWEEN 0 AND 5 OR b BETWEEN 0 AND 5)

by 마농 [2009.04.23 11:05:19]
단순 수식계산으로 500 보다 작다고 하면 안됩니다.
19:59:00 과 20:01:00 은 실제로는 2분차이이지만 숫자로 빼면 4200 이 됩니다.

by Ejql [2009.04.23 13:44:22]
2,8,10번째 로우가 결과에 포함되는 이유좀 알려주세요. 이전 기록성공이후 5분이상이 되는것들입니다.

제가 못보고 있는것이 있는가요? ^^;

by 서성우 [2009.04.23 13:59:51]
2,8,10 번째가 있는 이유는

로우비교를
이전 로우나 다음로우의 텀이 5분이하인 것들
을 출력하는 것이라 포함 되는 것 입니다.

by Ejql [2009.04.23 14:03:41]
넵. 감사합니다.

by 마농 [2009.04.23 14:37:32]
문제에 오해의 소지가 분명 있었네요.
설명대로만 한다면 빠지는게 맞겠죠. 제가 설명릉 잘못했네요.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입