아래와 같은 결과가 있다고 하면
with t as (
select 1 as seq, 'PROD_1' as prod, to_date('20211028','yyyymmdd') as sal_date, 100 as amt from dual union all
select 2 as seq, 'PROD_1' as prod, to_date('20210515','yyyymmdd') as sal_date, 200 as amt from dual union all
select 3 as seq, 'PROD_1' as prod, to_date('20201120','yyyymmdd') as sal_date, 300 as amt from dual union all
select 4 as seq, 'PROD_1' as prod, to_date('20191010','yyyymmdd') as sal_date, 200 as amt from dual )
select *
from t ;
이때 첫번째(최근) 레코드 기준으로 6개월이내, 12개월이내, 24개일이내의 합계를 구하고자합니다.
원하는 결과는
항목 6개월이내 12개월이내 24개월이내
PROD_1 300 600 800
감사합니다.
첫번째(최근) 레코드 기준으로 라는게 '20211028' 일자 기준으로 6개월, 12개월, 24개월 에 해당 하는 amt 들의 합인가요??
20211028 기준으로 하면
6개월이내 : 20211028 ~20210428
12개월이내 : 20211028 ~20201028
24개월이내 : 20211028 ~20191028
그럼 24개월은 600 이지 않나요?
WITH T AS ( SELECT 1 AS SEQ, 'PROD_1' AS PROD, TO_DATE('20211028','YYYYMMDD') AS SAL_DATE, 100 AS AMT FROM DUAL UNION ALL SELECT 2 AS SEQ, 'PROD_1' AS PROD, TO_DATE('20210515','YYYYMMDD') AS SAL_DATE, 200 AS AMT FROM DUAL UNION ALL SELECT 3 AS SEQ, 'PROD_1' AS PROD, TO_DATE('20201120','YYYYMMDD') AS SAL_DATE, 300 AS AMT FROM DUAL UNION ALL SELECT 4 AS SEQ, 'PROD_1' AS PROD, TO_DATE('20191010','YYYYMMDD') AS SAL_DATE, 200 AS AMT FROM DUAL ) SELECT PROD , SUM(M6) "6개월이내" , SUM(M12) "12개월이내" , SUM(M24) "24개월이내" FROM ( SELECT PROD , SAL_DATE , F_SAL_DATE , P_SAL_DATE , ADD_MONTHS(F_SAL_DATE, -6) , ADD_MONTHS(F_SAL_DATE, -12) , ADD_MONTHS(F_SAL_DATE, -24) , CASE WHEN SAL_DATE BETWEEN ADD_MONTHS(F_SAL_DATE, -6) AND F_SAL_DATE THEN AMT END M6 , CASE WHEN SAL_DATE BETWEEN ADD_MONTHS(F_SAL_DATE, -12) AND F_SAL_DATE THEN AMT END M12 , CASE WHEN SAL_DATE BETWEEN ADD_MONTHS(F_SAL_DATE, -24) AND F_SAL_DATE THEN AMT END M24 FROM ( SELECT FIRST_VALUE(SAL_DATE) OVER (ORDER BY SAL_DATE DESC ROWS UNBOUNDED PRECEDING) AS F_SAL_DATE , LAG(SAL_DATE, 1, SAL_DATE) OVER (ORDER BY SAL_DATE DESC) AS P_SAL_DATE , T.* FROM T ORDER BY SAL_DATE DESC ) ) GROUP BY PROD ;
-- 샘플 기준이 맞다면 월단위 기준인가요? 일별 기준이 맞다면 TO_CHAR() 제거하시면 됩니다. WITH t AS ( select 1 as seq, 'PROD_1' as prod, to_date('20211028','yyyymmdd') as sal_date, 100 as amt from dual union all select 2 as seq, 'PROD_1' as prod, to_date('20210515','yyyymmdd') as sal_date, 200 as amt from dual union all select 3 as seq, 'PROD_1' as prod, to_date('20201120','yyyymmdd') as sal_date, 300 as amt from dual union all select 4 as seq, 'PROD_1' as prod, to_date('20191010','yyyymmdd') as sal_date, 200 as amt from dual ) SELECT prod, max(mm6) AS "6개월이내", max(mm12) AS "12개월이내", max(mm24) AS "24개월이내" FROM ( SELECT t.prod , CASE WHEN TO_CHAR(t.sal_date, 'yyyymm') <= TO_CHAR(B.sal_date, 'yyyymm') AND TO_CHAR(t.sal_date, 'yyyymm') >= TO_CHAR(ADD_MONTHS(B.sal_date, -6), 'yyyymm') THEN SUM(amt) OVER(ORDER BY t.sal_date DESC) ELSE 0 END mm6 , CASE WHEN TO_CHAR(t.sal_date, 'yyyymm') <= TO_CHAR(B.sal_date, 'yyyymm') AND TO_CHAR(t.sal_date, 'yyyymm') >= TO_CHAR(ADD_MONTHS(B.sal_date, -12), 'yyyymm') THEN SUM(amt) OVER(ORDER BY t.sal_date DESC) ELSE 0 END mm12 , CASE WHEN TO_CHAR(t.sal_date, 'yyyymm') <= TO_CHAR(B.sal_date, 'yyyymm') AND TO_CHAR(t.sal_date, 'yyyymm') >= TO_CHAR(ADD_MONTHS(B.sal_date, -24), 'yyyymm') THEN SUM(amt) OVER(ORDER BY t.sal_date DESC) ELSE 0 END mm24 FROM t LEFT JOIN ( SELECT prod , sal_date FROM t WHERE ROWNUM = 1 ORDER BY sal_date DESC ) B ON t.prod = B.prod ) AA GROUP BY prod
결과표가 애매합니다.
기간 산정 기준이 명확해야 합니다.
6개월 이내의 정확한 기간을 알려주세요.
20210429 ~ 20211028 : 일단위(6개월)
20210428 ~ 20211028 : 일단위(6개월) + 1일
20210501 ~ 20211031 : 월단위(6개월)
???????? ~ ???????? : 기타?
WITH t AS ( SELECT 1 seq, 'PROD_1' prod, TO_DATE('20211028', 'yyyymmdd') sal_date, 100 amt FROM dual UNION ALL SELECT 2, 'PROD_1', TO_DATE('20210515', 'yyyymmdd'), 200 FROM dual UNION ALL SELECT 3, 'PROD_1', TO_DATE('20201120', 'yyyymmdd'), 300 FROM dual UNION ALL SELECT 4, 'PROD_1', TO_DATE('20191010', 'yyyymmdd'), 200 FROM dual ) SELECT prod , m06 , m12 , m24 FROM (SELECT seq, prod, sal_date, amt , SUM(amt) OVER(PARTITION BY prod ORDER BY sal_date RANGE INTERVAL '6' MONTH PRECEDING) m06 , SUM(amt) OVER(PARTITION BY prod ORDER BY sal_date RANGE INTERVAL '12' MONTH PRECEDING) m12 , SUM(amt) OVER(PARTITION BY prod ORDER BY sal_date RANGE INTERVAL '24' MONTH PRECEDING) m24 , ROW_NUMBER() OVER(PARTITION BY prod ORDER BY sal_date DESC) rn FROM t ) WHERE rn = 1 ;
WITH t AS ( SELECT 1 seq, 'PROD_1' prod, TO_DATE('20211028', 'yyyymmdd') sal_date, 100 amt FROM dual UNION ALL SELECT 2, 'PROD_1', TO_DATE('20210515', 'yyyymmdd'), 200 FROM dual UNION ALL SELECT 3, 'PROD_1', TO_DATE('20201120', 'yyyymmdd'), 300 FROM dual UNION ALL SELECT 4, 'PROD_1', TO_DATE('20191010', 'yyyymmdd'), 200 FROM dual ) SELECT prod , SUM(CASE WHEN mm <= 6 THEN amt END) m06 , SUM(CASE WHEN mm <= 12 THEN amt END) m12 , SUM(CASE WHEN mm <= 24 THEN amt END) m24 FROM (SELECT seq, prod, sal_date, amt , MONTHS_BETWEEN(MAX(sal_date) OVER(PARTITION BY prod), sal_date) mm FROM t ) WHERE mm <= 24 GROUP BY prod ;