by 둥둥맨 [SQL Query] sequence SQL fill [2020.07.17 10:07:34]
안녕하세요,
주차별 테이블 생성 후 2주차까지만 특정값 입력을 하고자 할 때 쿼리 질문드립니다.
입력테이블
yyyy | ww | ymd | id | value |
2020 | 1 | 2020-01-01 | AAA | K |
2020 | 2 | 2020-01-08 | AAA | J |
2020 | 5 | 2020-02-04 | BBB | H |
... | ... | ... | ... | ... |
위와 같은 입력 테이블이 있습니다. yyyy연도와 ww주차는 ymd와 연동이 됩니다.
id기준으로 특정 주차 특정날짜에 K, J, H 등 값이 들어가있습니다.
원하는 아웃풋
시작주차를 기준으로 2주마다 동일한 값이 들어있는 테이블을 만들고자 합니다.
이 때 시작주차+1주차에 값이 있는 경우 기존값 유지(첫번째 row에서 보면 2020 1주차 AAA K값은 2주차에 다른 값이 있으므로 2주차 데이터를 새로 생성하지 않고 기존에 있던 J값을 유지),
시작주차+1주차에 값이 없는 경우 +1주차 행을 생성하면서 시작주차값을 가져오기(2번째 row의 2020 2 AAA J값은 3주차에 J로 생성)
yyyy | ww | id | value |
2020 | 1 | AAA | K |
2020 | 2 | AAA | J |
2020 | 3 | AAA | J |
2020 | 5 | BBB | H |
2020 | 6 | BBB | H |
... | ... | ... | ... |
전에 드린 질문과 약간 유사하나 잘 되지 않아 질문드려봅니다. 미리 답변에 감사드립니다.
WITH t AS ( SELECT '2020' yyyy, 1 ww, 'AAA' id, 'K' val FROM dual UNION ALL SELECT '2020', 2, 'AAA', 'J' FROM dual UNION ALL SELECT '2020', 5, 'BBB', 'H' FROM dual ) SELECT a.yyyy , a.ww + c.lv - 1 ww , a.id , a.val FROM t a LEFT OUTER JOIN t b ON a.yyyy = b.yyyy AND a.id = b.id AND a.ww + 1 = b.ww INNER JOIN (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 2) c ON c.lv <= NVL2(b.id, 1, 2) WHERE a.yyyy = '2020' ORDER BY id, ww ;
특정 구문이 꼭 필요하다거나? (Case 가 왜 안들어 가지?)
특정 구문으로 문제가 해결된다고 단정지으면 안됩니다. (Connect By Level 로 처리되는건가?)
가장 적당하다고 생각되는 여러 구문들을 조합하여 결과를 만들어 내는 것일 뿐입니다. (적재적소)
선입견을 가지고 답변에 대한 섣부른 판단을 하지 마세요.
판단 부터 우선 하지 말고, 일단 실행부터 해보고 난 뒤에 판단하세요.
위 답변에서는 NVL2 가 CASE 문과 같은 역할을 합니다.
ON c.lv <= NVL2(b.id, 1, 2)
ON c.lv <= CASE WHEN b.id IS NULL THEN 2 ELSE 1 END