공백시간 존재여부 찾는 쿼리 질문입니다.. 1 5 1,803

by 종이남자 [SQL Query] [2014.12.29 10:40:54]


안녕하세요..


SELECT 1 AS SEQ, 'TCH1' AS TCH, '12:55' AS STA_TH, '13:05' AS END_TH FROM DUAL
UNION ALL
SELECT 2 AS SEQ, 'TCH1' AS TCH, '13:10' AS STA_TH, '13:20' AS END_TH FROM DUAL
UNION ALL
SELECT 3 AS SEQ, 'TCH1' AS TCH, '13:30' AS STA_TH, '13:40' AS END_TH FROM DUAL
UNION ALL
SELECT 4 AS SEQ, 'TCH1' AS TCH, '13:40' AS STA_TH, '13:50' AS END_TH FROM DUAL
UNION ALL
SELECT 5 AS SEQ, 'TCH1' AS TCH, '13:55' AS STA_TH, '14:05' AS END_TH FROM DUAL
UNION ALL
SELECT 6 AS SEQ, 'TCH2' AS TCH, '12:45' AS STA_TH, '12:55' AS END_TH FROM DUAL
UNION ALL
SELECT 7 AS SEQ, 'TCH2' AS TCH, '13:05' AS STA_TH, '13:15' AS END_TH FROM DUAL
UNION ALL
SELECT 8 AS SEQ, 'TCH2' AS TCH, '13:15' AS STA_TH, '13:25' AS END_TH FROM DUAL
UNION ALL
SELECT 9 AS SEQ, 'TCH2' AS TCH, '13:30' AS STA_TH, '13:40' AS END_TH FROM DUAL
UNION ALL
SELECT 10 AS SEQ, 'TCH2' AS TCH, '13:45' AS STA_TH, '13:55' AS END_TH FROM DUAL

 

오라클에서 위와 같은 교사 일정 테이블이 있을때... 13시부터 14시까지 연속 10분이상 공백이 있는 교사를 추출해야 하는데

어떻게 해야할지 모르겠습니다..

위 데이터에서는 13:05~13:10, 13:20~13:30 공백이 있는

TCH1 만 나와야합니다.

어떻게 풀어야 할까요?

by 아발란체 [2014.12.29 11:48:07]

TCH2도 나와야 하는 것 아닌가요?

seq, 6에서 7로 넘어갈 때 12:55에 종료하고 13:05분에 시작하여 10분 차이가 발생합니다.

WITH T AS (
  SELECT 1 AS SEQ, 'TCH1' AS TCH, '12:55' AS STA_TH, '13:05' AS END_TH FROM DUAL
  UNION ALL
  SELECT 2 AS SEQ, 'TCH1' AS TCH, '13:10' AS STA_TH, '13:20' AS END_TH FROM DUAL
  UNION ALL
  SELECT 3 AS SEQ, 'TCH1' AS TCH, '13:30' AS STA_TH, '13:40' AS END_TH FROM DUAL
  UNION ALL
  SELECT 4 AS SEQ, 'TCH1' AS TCH, '13:40' AS STA_TH, '13:50' AS END_TH FROM DUAL
  UNION ALL
  SELECT 5 AS SEQ, 'TCH1' AS TCH, '13:55' AS STA_TH, '14:05' AS END_TH FROM DUAL
  UNION ALL
  SELECT 6 AS SEQ, 'TCH2' AS TCH, '12:45' AS STA_TH, '12:55' AS END_TH FROM DUAL
  UNION ALL
  SELECT 7 AS SEQ, 'TCH2' AS TCH, '13:05' AS STA_TH, '13:15' AS END_TH FROM DUAL
  UNION ALL
  SELECT 8 AS SEQ, 'TCH2' AS TCH, '13:15' AS STA_TH, '13:25' AS END_TH FROM DUAL
  UNION ALL
  SELECT 9 AS SEQ, 'TCH2' AS TCH, '13:30' AS STA_TH, '13:40' AS END_TH FROM DUAL
  UNION ALL
  SELECT 10 AS SEQ, 'TCH2' AS TCH, '13:45' AS STA_TH, '13:55' AS END_TH FROM DUAL
)
SELECT
  seq, tch,
  sta_th, end_th, 
  MOD(TO_DATE(sta_th, 'HH24:MI') - TO_DATE(prev_sta_th, 'HH24:MI'), 1) * 24 * 60 AS gap
FROM (
  SELECT
    seq, tch, sta_th, end_th, NVL(LAG(end_th) OVER(PARTITION BY tch ORDER BY seq), sta_th) prev_sta_th
  FROM
    T
)
WHERE
  MOD(TO_DATE(sta_th, 'HH24:MI') - TO_DATE(prev_sta_th, 'HH24:MI'), 1) * 24 * 60 >= 10
;

 


by 종이남자 [2014.12.29 13:02:41]

13시부터 연속 10분이상만 나와야 하는거라

13시 05분까지 5분공백인 TCH2 는 나오지 않는게 맞습니다.


by 아발란체 [2014.12.29 13:16:44]
-- @.@)ㆀ 단서가 있었군요... 죄송합니다.
SELECT
  seq, tch,
  sta_th, end_th, 
  MOD(TO_DATE(sta_th, 'HH24:MI') - TO_DATE(prev_sta_th, 'HH24:MI'), 1) * 24 * 60 AS gap
FROM (
  SELECT
    seq, tch, sta_th, end_th, NVL(LAG(end_th) OVER(PARTITION BY tch ORDER BY seq), sta_th) prev_sta_th
  FROM
    T
  WHERE
    TO_CHAR(TO_DATE(sta_th, 'HH24:MI'), 'HH24MI') BETWEEN '1300' AND '1400'
)
WHERE
  MOD(TO_DATE(sta_th, 'HH24:MI') - TO_DATE(prev_sta_th, 'HH24:MI'), 1) * 24 * 60 >= 10
;

 


by 마농 [2014.12.29 13:19:15]

1. 검색 조건 시간(13~14시)이 주어져서 그런듯 하네요.
2. 주어진 자료검색만으로는 부족할 듯 합니다.
  - 주어진 자료에서 Lag, Lead 를 이용한다면? 답이 나오긴 합니다.
3. 그러나 예외적인 자료가 더 존재한다면?
  - 교사3은 13:20~13:40 자료 한건만 존재한다면?
    13:00~13:20, 13:40~14:00 이렇게 두개의 공백시간을 구해야 하는데?
    테이블 검색의 Lag, Lead 만으로 없는 시간을 만들기 어렵습니다.
  - 교사4는 교사 테이블에는 존재하는데 13:00~14:00 사이에 아무런 자료가 없다면?
    교사4 도 검색조건상 13:00~14:00 가 공백기간으로 나와야 할 듯 하네요?


결론은.
주어진 자료만 활용하는 거라면 LAG 를 이용하여 쉽게 구할 수 있습니다.
3,4번 케이스까지 뽑아야 하는 거라면? 좀더 복잡한 과정을 거쳐서 구해야 할 듯 하네요.


by 종이남자 [2014.12.29 13:47:09]

감사합니다.

마농님이 지적해주신 4번째 케이스는 말씀안드렸는데 찝어내셨네요..

아발란체님처럼 LAG을 이용해서 이전 타임과 갭을 구하고

교사테이블 base로 갭구하는view를 outer로 걸어서 강제적으로 nvl(갭, 10) 으로 하는 방향으로 하면

될 것 같기도 합니다..

공백시간이 10분 이상 있는 '사람' 만 구하면 되는거라서 한타임이던 두타임이던 상관이 없으니

갭 >= 10 조건을 마지막에 걸고 distinct 로 교사번호를 뽑아올까 합니다.

두분 모두 감사합니다.

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