안녕하세요. 이번 한주도 고생 많으셨습니다 ㅎㅎ
원하는 방향으로 로직을 구현하긴 했는데, 조금 로직을 단순화 할 수 있는 방향을 생각해보다가 문의드리게 되었습니다.
기준일 (1/15) 기준으로 1/12 ~ 1/14 일 구간의 (요구합계 - 적용합계) 를 기준일 이후로 요구가 있는 가장 빠른 날에 더해주는 로직 입니다.
샘플 테이블의 T1 = 요구 테이블, T2 = 적용 테이블 입니다.
로직을 짜긴 짰는데.. 짜다보니 요구 테이블을 모수로 3번이나 활용하였습니다...
1. ( 요구 - 수량 ) 구할 때,
2. 1에서 구한 수량, 구간 이후 수량있는일자에 더해주고, 가장 최근 일자만 발췌.
3. NVL(요구테이블수량, 2에서 구한 가장최근일자 수량)
뭔가 동일한 테이블 3번쓴게 찝찝한데 뭔가 해결을 못하고있어서 문의드려봅니다..
베이스 데이터
GROUP1 | TYPE | 1월 12일 | 1월 13일 | 1월 14일 | 1월 15일 | 1월 16일 | 1월 17일 | 1월 18일 | 1월 19일 | 1월 20일 | 1월 21일 | 1월 22일 | 1월 23일 |
A | 요구 | 100 | 100 | 100 | 100 | 100 | 100 | ||||||
A | 적용 | ||||||||||||
B | 요구 | 100 | 100 | 100 | 100 | ||||||||
B | 적용 |
요구 수량 적용
기준일 | |||||||||||||
GROUP1 | TYPE | 1월 12일 | 1월 13일 | 1월 14일 | 1월 15일 | 1월 16일 | 1월 17일 | 1월 18일 | 1월 19일 | 1월 20일 | 1월 21일 | 1월 22일 | 1월 23일 |
A | 요구 | 100 | 100 | 100 | 365 | 100 | |||||||
A | 적용 | 5 | 20 | 10 | |||||||||
B | 요구 | 100 | 100 | 290 | 100 | ||||||||
B | 적용 | 5 | 5 |
WITH T1 AS (
SELECT 'A' AS GROUP1, TO_DATE('20240112','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'A' AS GROUP1, TO_DATE('20240113','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'A' AS GROUP1, TO_DATE('20240114','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'A' AS GROUP1, TO_DATE('20240116','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'A' AS GROUP1, TO_DATE('20240117','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'B' AS GROUP1, TO_DATE('20240112','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'B' AS GROUP1, TO_DATE('20240113','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'B' AS GROUP1, TO_DATE('20240119','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
UNION ALL
SELECT 'B' AS GROUP1, TO_DATE('20240123','YYYYMMDD') AS PLANDATE, 100 수량 FROM DUAL
),
T2 AS (
SELECT 'A' AS GROUP1, TO_DATE('20240112','YYYYMMDD') AS RESULTDATE, 5 수량 FROM DUAL
UNION ALL
SELECT 'A' AS GROUP1, TO_DATE('20240113','YYYYMMDD') AS RESULTDATE, 20 수량 FROM DUAL
UNION ALL
SELECT 'A' AS GROUP1, TO_DATE('20240114','YYYYMMDD') AS RESULTDATE, 10 수량 FROM DUAL
UNION ALL
SELECT 'B' AS GROUP1, TO_DATE('20240112','YYYYMMDD') AS RESULTDATE, 5 수량 FROM DUAL
UNION ALL
SELECT 'B' AS GROUP1, TO_DATE('20240113','YYYYMMDD') AS RESULTDATE, 5 수량 FROM DUAL
)
SELECT A.GROUP1, A.PLANDATE, NVL(B.요구SUM, A.요구) AS QTY
FROM (
SELECT GROUP1, PLANDATE, 수량 as 요구
FROM T1
WHERE PLANDATE BETWEEN TO_DATE('20240112','YYYYMMDD') AND TO_DATE('20240125','YYYYMMDD')
) A,
(
SELECT A.GROUP1, A.PLANDATE, 요구SUM
FROM (
SELECT A.GROUP1, A.PLANDATE, A.요구 AS 요구, B.적용, B.부족, (A.요구+B.부족) AS 요구SUM,
ROW_NUMBER() OVER(PARTITION BY A.GROUP1 ORDER BY PLANDATE) RNK
FROM (
SELECT GROUP1, PLANDATE, 수량 AS 요구
FROM T1
WHERE PLANDATE BETWEEN TO_DATE('20240112','YYYYMMDD') AND TO_DATE('20240125','YYYYMMDD')
AND PLANDATE > TO_DATE('20240114','YYYYMMDD')
) A,
(
SELECT A.GROUP1 AS GROUP1, A.요구 , B.적용 , (A.요구 - B.적용) AS 부족
FROM (
SELECT GROUP1, SUM(수량) AS 요구
FROM T1
WHERE PLANDATE BETWEEN TO_DATE('20240112','YYYYMMDD') AND TO_DATE('20240114','YYYYMMDD')
GROUP BY GROUP1
) A,
(
SELECT GROUP1, SUM(수량) AS 적용
FROM T2
WHERE RESULTDATE BETWEEN TO_DATE('20240112','YYYYMMDD') AND TO_DATE('20240114','YYYYMMDD')
GROUP BY GROUP1
) B
WHERE A.GROUP1 = B.GROUP1(+)
AND A.요구 > B.적용
) B
WHERE A.GROUP1 = B.GROUP1(+)
) A
WHERE RNK = 1
) B
WHERE A.GROUP1 = B.GROUP1(+)
AND A.PLANDATE = B.PLANDATE(+)
ORDER BY A.GROUP1, A.PLANDATE ASC;
GROUP DATE 수량
A 24/01/12 100
A 24/01/13 100
A 24/01/14 100
A 24/01/16 365
A 24/01/17 100
B 24/01/12 100
B 24/01/13 100
B 24/01/19 290
B 24/01/23 100
SELECT GROUP1, TO_CHAR(PLANDATE, 'YYYY-MM-DD') AS 날짜 , CASE WHEN RN = 1 THEN ( sum(CASE WHEN PLANDATE < '2024-01-15' then 요구 ELSE 0 END ) over(PARTITION BY GROUP1) ) + 요구 - ( sum(적용) over(PARTITION BY GROUP1) ) ELSE 요구 END AS 수량 FROM ( SELECT T1.GROUP1, T1.PLANDATE, T1.수량 AS 요구, T2.RESULTDATE, T2.수량 AS 적용 , TRN.rn FROM T1 LEFT JOIN T2 ON T1.GROUP1 = T2.GROUP1 AND T1.PLANDATE = T2.RESULTDATE LEFT JOIN( SELECT T1.PLANDATE , ROW_NUMBER() over(PARTITION BY GROUP1 ORDER BY PLANDATE) rn FROM T1 WHERE PLANDATE > '2024-01-15' ) TRN ON TRN.rn = 1 AND TRN.PLANDATE = T1.PLANDATE ) tbl WHERE PLANDATE <> '2024-01-15' -- 베이스데이터 표에는 15일 값이 있어서 결과에 제외 조건 추가 ORDER BY GROUP1, PLANDATE
WITH t1 AS ( SELECT 'A' group1, TO_DATE('20240112', 'yyyymmdd') plandate, 100 수량 FROM dual UNION ALL SELECT 'A', TO_DATE('20240113', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'A', TO_DATE('20240114', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'A', TO_DATE('20240116', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'A', TO_DATE('20240117', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'B', TO_DATE('20240112', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'B', TO_DATE('20240113', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'B', TO_DATE('20240119', 'yyyymmdd'), 100 수량 FROM dual UNION ALL SELECT 'B', TO_DATE('20240123', 'yyyymmdd'), 100 수량 FROM dual ) , t2 AS ( SELECT 'A' group1, TO_DATE('20240112', 'yyyymmdd') resultdate, 5 수량 FROM dual UNION ALL SELECT 'A', TO_DATE('20240113', 'yyyymmdd'), 20 수량 FROM dual UNION ALL SELECT 'A', TO_DATE('20240114', 'yyyymmdd'), 10 수량 FROM dual UNION ALL SELECT 'B', TO_DATE('20240112', 'yyyymmdd'), 5 수량 FROM dual UNION ALL SELECT 'B', TO_DATE('20240113', 'yyyymmdd'), 5 수량 FROM dual ) SELECT a.group1 , a.plandate , DECODE(a.plandate, a.일자, a.요구 - NVL(b.적용, 0), a.수량) qty FROM (SELECT group1 , plandate , 수량 , MIN(CASE WHEN plandate > TO_DATE('20240114', 'yyyymmdd') THEN plandate END) OVER(PARTITION BY group1) 일자 , SUM(수량) OVER(PARTITION BY group1 ORDER BY plandate) 요구 FROM t1 WHERE plandate >= TO_DATE('20240112', 'yyyymmdd') AND plandate <= TO_DATE('20240125', 'yyyymmdd') ) a , (SELECT group1 , SUM(수량) 적용 FROM t2 WHERE resultdate >= TO_DATE('20240112', 'yyyymmdd') AND resultdate <= TO_DATE('20240114', 'yyyymmdd') GROUP BY group1 ) b WHERE a.group1 = b.group1(+) ORDER BY a.group1, a.plandate ;