매일 구간 합산을 합산을 구하고 싶습니다. 0 4 587

by 푸릉이 [2018.09.17 14:23:12]


WITH T AS 
(
SELECT '20170101' YMD, 'A' DPT, 1 CNT FROM DUAL UNION ALL  
SELECT '20170102' YMD, 'B' DPT, 2 CNT FROM DUAL UNION ALL
SELECT '20170103' YMD, 'C' DPT, 3 CNT FROM DUAL UNION ALL
SELECT '20170104' YMD, 'A' DPT, 1 CNT FROM DUAL UNION ALL
  
SELECT '20180102' YMD, 'B' DPT, 2 CNT FROM DUAL UNION ALL
SELECT '20180103' YMD, 'C' DPT, 3 CNT FROM DUAL UNION ALL
SELECT '20180108' YMD, 'A' DPT, 5 CNT FROM DUAL UNION ALL
SELECT '20180109' YMD, 'B' DPT, 6 CNT FROM DUAL
SELECT '20180916' YMD, 'D' DPT, 77 CNT FROM DUAL)
SELECT * FROM  T

                 1년전 1월1일부터 어제            이번년도 1월1일부터 어제
20180916 A 2(20170101~20170915까지 CNT합산)   5(20180101~20180915까지 합산)  
20180916 B 2         8
20180916 C 3         3
20180916 D 0         0
20180917 A 2(20170101~20170916까지 CNT합산)   5(20180101~20180916까지 합산)  
20180917 B 2         8
20180917 C 3         3
20180917 D 0         77

(20170101~20170916까지 CNT합산) 이문구는 이해를 돕기위한 주석입니다.

이런식으로 오늘 조회하면 10일전까지 날짜별 고정 4개의 부서에 대해서 누적 카운트를 추출하려고 합니다.
어떻게 짜야할까요? 

by 신이만든지기 [2018.09.17 15:01:26]
WITH
    T AS
        (SELECT '20170101' YMD, 'A' DPT, 1 CNT FROM DUAL
         UNION ALL
         SELECT '20170102' YMD, 'B' DPT, 2 CNT FROM DUAL
         UNION ALL
         SELECT '20170103' YMD, 'C' DPT, 3 CNT FROM DUAL
         UNION ALL
         SELECT '20170104' YMD, 'A' DPT, 1 CNT FROM DUAL
         UNION ALL
         SELECT '20180102' YMD, 'B' DPT, 2 CNT FROM DUAL
         UNION ALL
         SELECT '20180103' YMD, 'C' DPT, 3 CNT FROM DUAL
         UNION ALL
         SELECT '20180108' YMD, 'A' DPT, 5 CNT FROM DUAL
         UNION ALL
         SELECT '20180109' YMD, 'B' DPT, 6 CNT FROM DUAL
         UNION ALL
         SELECT '20180916' YMD, 'D' DPT, 77 CNT FROM DUAL)
  SELECT Y.THIS_YESTERDAY + 1 AS YMD
       , T.DPT
       , NVL(SUM(CASE WHEN TO_DATE(YMD, 'YYYYMMDD') BETWEEN Y.LAST_YEAR AND Y.LAST_YESTERDAY THEN CNT END), 0) LAST_YEAR_CNT
       , NVL(SUM(CASE WHEN TO_DATE(YMD, 'YYYYMMDD') BETWEEN Y.THIS_YEAR AND Y.THIS_YESTERDAY THEN CNT END), 0) THIS_YEAR_CNT
    FROM T
       , (    SELECT TRUNC(SYSDATE, 'YEAR')            THIS_YEAR
                   , TRUNC(SYSDATE) - LEVEL            THIS_YESTERDAY
                   , ADD_MONTHS(TRUNC(SYSDATE, 'YEAR'), -12) LAST_YEAR
                   , ADD_MONTHS(TRUNC(SYSDATE), -12) - LEVEL LAST_YESTERDAY
                FROM DUAL
          CONNECT BY LEVEL <= 10) Y
GROUP BY Y.THIS_YESTERDAY, T.DPT
ORDER BY Y.THIS_YESTERDAY ASC, T.DPT ASC;

 


by 푸릉이 [2018.09.17 16:29:20]

정확하게 원하는 결과나 나오네요 감사합니다.


by 마농 [2018.09.17 15:20:26]
WITH t AS 
(
SELECT '20170101' ymd, 'A' dpt, 1 cnt FROM dual   
UNION ALL SELECT '20170102', 'B',  2 FROM dual 
UNION ALL SELECT '20170103', 'C',  3 FROM dual 
UNION ALL SELECT '20170104', 'A',  1 FROM dual 
UNION ALL SELECT '20180102', 'B',  2 FROM dual 
UNION ALL SELECT '20180103', 'C',  3 FROM dual 
UNION ALL SELECT '20180108', 'A',  5 FROM dual 
UNION ALL SELECT '20180109', 'B',  6 FROM dual
UNION ALL SELECT '20180916', 'D', 77 FROM dual
)
, t_ymd AS
(
SELECT TO_CHAR(                 dt                , 'yyyymmdd') ymd
     , TO_CHAR(TRUNC(ADD_MONTHS(dt    , -12), 'y'), 'yyyymmdd') symd_1
     , TO_CHAR(      ADD_MONTHS(dt - 1, -12)      , 'yyyymmdd') eymd_1
     , TO_CHAR(TRUNC(           dt          , 'y'), 'yyyymmdd') symd_2
     , TO_CHAR(                 dt - 1            , 'yyyymmdd') eymd_2
  FROM (SELECT TRUNC(sysdate) - LEVEL + 1 dt
          FROM dual
         CONNECT BY LEVEL <= 10
        )
)
, t_dpt AS
(
SELECT 'A' dpt FROM dual
UNION ALL SELECT 'B' FROM dual
UNION ALL SELECT 'C' FROM dual
UNION ALL SELECT 'D' FROM dual
)
SELECT a.ymd
     , b.dpt
     , NVL(SUM(CASE WHEN c.ymd <= a.eymd_1 THEN cnt END), 0) cnt_1
     , NVL(SUM(CASE WHEN c.ymd >= a.symd_2 THEN cnt END), 0) cnt_2
  FROM t_ymd a
 CROSS JOIN t_dpt b
  LEFT OUTER JOIN t c
    ON b.dpt = c.dpt
   AND c.ymd BETWEEN a.symd_1 AND a.eymd_2
 GROUP BY a.ymd, b.dpt
 ORDER BY a.ymd, b.dpt
;

 


by 푸릉이 [2018.09.17 16:29:47]

아~ 정말 감탄이 나오네요.

위의 쿼리는 초반에 해당년도에 건수가 없으면 누락되네요.

마농님건 잘나오구요.

감사합니다.

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