부분합계 1 3 538

by axelhoon [SQL Query] 분석함수 [2021.10.29 16:54:04]


아래와 같은 결과가 있다고 하면

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

 

감사합니다.

by 동동동 [2021.10.29 18:04:27]

첫번째(최근) 레코드 기준으로 라는게 '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
 ;

 


by 뉴비디비 [2021.10.30 20:26:15]
-- 샘플 기준이 맞다면 월단위 기준인가요? 일별 기준이 맞다면 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

 


by 마농 [2021.11.01 09:13:13]

결과표가 애매합니다.
기간 산정 기준이 명확해야 합니다.
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
;

 

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