안녕하세요 쿼리 작성을 어떻게 해야 좋을지 문의드립니다.
조회 기간에 대한 비가동 실적을 조별로 시간 합계를 내야합니다.
조별기준은
06:30~ 14:30 1조
14:30~ 22:30 2조
22:30~ 06:30 3조
이고
비가동실적이 아래와 같을때
1. 2015/12/20 07:00:00 ~ 2015/12/20 09:00:00
2. 2015/12/21 15:00:00 ~ 2015/12/21 23:50:00
3. 2015/12/22 08:00:00 ~ 2015/12/25 17:00:00
일자 1조 2조 3조
20 120
21 450 80
22 90 480 480
23 480 480 480
24 480 480 480
25 480 150 0
TOT 2070 3240 1520
위처럼 합계 계산되어 최종적으로 tot 에 해당하는 값을 결과값으로 가져올 방법이 있을지 문의드립니다.
with t as (select to_date('2015-12-20 07:00:00','yyyy-mm-dd hh24:mi:ss') stime, to_date('2015-12-20 09:00:00','yyyy-mm-dd hh24:mi:ss') etime from dual union all select to_date('2015-12-21 15:00:00','yyyy-mm-dd hh24:mi:ss') stime, to_date('2015-12-21 23:50:00','yyyy-mm-dd hh24:mi:ss') etime from dual union all select to_date('2015-12-22 08:00:00','yyyy-mm-dd hh24:mi:ss') stime, to_date('2015-12-25 17:00:00','yyyy-mm-dd hh24:mi:ss') etime from dual ) SELECT stime , etime , SUM(ROUND (NVL ((etime1 - stime1) * 24 * 60, 0))) time1 , SUM(ROUND (NVL ((etime2 - stime2) * 24 * 60, 0))) time2 , SUM(ROUND (NVL ((etime3 - stime3) * 24 * 60, 0) + NVL ((etime31 - stime31) * 24 * 60, 0))) time3 FROM (SELECT stime , etime , CASE WHEN stime >= TRUNC (stime) + 6.5 / 24 AND stime < TRUNC (stime) + 14.5 / 24 THEN stime WHEN stime < TRUNC (stime) + 6.5 / 24 THEN TRUNC (stime) + 6.5 / 24 END stime1 , CASE WHEN etime >= TRUNC (etime) + 6.5 / 24 AND etime < TRUNC (etime) + 14.5 / 24 THEN etime WHEN etime > TRUNC (etime) + 14.5 / 24 THEN TRUNC (etime) + 14.5 / 24 - 0.00001 END etime1 , CASE WHEN stime >= TRUNC (stime) + 14.5 / 24 AND stime < TRUNC (stime) + 22.5 / 24 THEN stime WHEN stime < TRUNC (stime) + 14.5 / 24 THEN TRUNC (stime) + 14.5 / 24 END stime2 , CASE WHEN etime >= TRUNC (etime) + 14.5 / 24 AND etime < TRUNC (etime) + 22.5 / 24 THEN etime WHEN etime > TRUNC (etime) + 22.5 / 24 THEN TRUNC (etime) + 22.5 / 24 - 0.00001 END etime2 , CASE WHEN stime >= TRUNC (stime) + 22.5 / 24 AND stime < TRUNC (stime) + 1 THEN stime WHEN stime < TRUNC (stime) + 22.5 / 24 THEN TRUNC (stime) + 22.5 / 24 END stime3 , CASE WHEN etime >= TRUNC (etime) + 22.5 / 24 AND etime < TRUNC (etime) + 1 THEN etime ELSE NULL END etime3 , CASE WHEN stime >= TRUNC (stime) AND stime < TRUNC (stime) + 06.5 / 24 THEN stime ELSE NULL END stime31 , CASE WHEN etime >= TRUNC (etime) AND etime < TRUNC (etime) + 06.5 / 24 THEN etime WHEN etime > TRUNC (etime) + 6.5 / 24 THEN TRUNC (etime) + 6.5 / 24 - 0.00001 END etime31 FROM (SELECT DECODE (TRUNC (stime), TRUNC (etime), stime, DECODE (lv, 1, stime, TRUNC (stime))) + lv - 1 stime , DECODE (TRUNC (stime) , TRUNC (etime), etime , DECODE (TRUNC (etime), TRUNC (stime) + lv - 1, etime, TRUNC (stime) + lv - 1 + 0.99999) ) etime FROM t , (SELECT LEVEL lv FROM DUAL CONNECT BY LEVEL < 3600) WHERE lv <= TRUNC (etime) - TRUNC (stime) + 1)) GROUP BY ROLLUP ((stime,etime))
더 간단하게 할 수 있을 것 같은데.. 머리가 안 좋으니 노가다네요;;
결과가 좀 다른데
22일 같은 경우 1조가 아침 8시부터 오후 14:30분까지 390분
3조가 오후 22시30분부터 24시까지 90분 이렇게 되어야 하는 것 아닌가요?
25일도 마찬가지구요. 확인해보세요.
WITH t AS ( SELECT 1 idx, '2015/12/20 07:00:00' stm, '2015/12/20 09:00:00' etm FROM dual UNION ALL SELECT 2, '2015/12/21 15:00:00', '2015/12/21 23:50:00' FROM dual UNION ALL SELECT 3, '2015/12/22 08:00:00', '2015/12/25 17:00:00' FROM dual ) SELECT TO_CHAR(s, 'yyyy/mm/dd') dt , ROUND(SUM(DECODE(lv2, 1, e - s)) *24*60) t1 , ROUND(SUM(DECODE(lv2, 2, e - s)) *24*60) t2 , ROUND(SUM(DECODE(lv2, 3, e - s)) *24*60) t3 FROM (SELECT lv2 , GREATEST(stm, TRUNC(stm) + lv1 - 1 + 8/24*(lv2-1)) s , LEAST (etm, TRUNC(stm) + lv1 - 1 + 8/24*(lv2 )) e FROM (SELECT idx , TO_DATE(stm, 'yyyy/mm/dd hh24:mi:ss') - 6.5/24 stm , TO_DATE(etm, 'yyyy/mm/dd hh24:mi:ss') - 6.5/24 etm FROM t ) , (SELECT LEVEL lv1 FROM dual CONNECT BY LEVEL <= 99) , (SELECT LEVEL lv2 FROM dual CONNECT BY LEVEL <= 3) WHERE lv1 <= TRUNC(etm) - TRUNC(stm) + 1 ) WHERE s < e GROUP BY ROLLUP(TO_CHAR(s, 'yyyy/mm/dd')) ORDER BY dt ;