쿼리질문 - Procedure를 활용한 최신데이터만 업데이트 할 때2 (oracle) 1 7 783

by 둥둥맨 [SQL Query] [2020.07.07 12:09:19]


안녕하세요, 제 설명이 명확하지 않아 재질문드립니다.

Procedure를 활용한 최신데이터만 업데이트 할 때 쿼리 질문드립니다.

log_ymd id join_ymd join_week  col1_yn col2_yn
20200101 AAA 20191223 50 y  
20200101 AAA 20191223 50   y
20200108 AAA 20191223 50 y y
20200109 AAA 20191223 50   y
20200101 BBB 20180101 1 y y
...          

위와 같은 테이블이 있습니다.

만들고자 하는 테이블은 다음과 같습니다.

row_no(FYI) log_yyyy log_week id join_yyyy join_week  col1_yn_count col2_yn_count week_past join_week_period
1 2020 1 AAA 2019 50 1 1 25 28
2 2020 2 AAA 2019 50 1 2 24 27
3 2020 1 BBB 2018 1 1 1 25 130
  ... ... ...            

log_yyyy와 log_week는 log_ymd에서 연도와 주차만 추출합니다. (join_yyyy, join_week도 동일)

id별 log_yyyy, log_week에 따라 주차별 col1_yn의 "Y"값 수를 col1_yn_count로 집계하는게 목적입니다.

 

여기서 Procedure를 사용하여 주단위로 row를 생성하고 싶습니다.

2번째 테이블(결과)에서 row_no(참고용) 중  2020년 1주차 code run 시 1번과 3번 row 결과가 나오고, 2주차 code run시 2번 row 결과가 나오기를 희망합니다(row 순서 무관), 이 때 procedure를 써서 현재주차(26주)까지 1주씩 업데이트가 되게끔 만들고자 합니다.

이 때 week_past는 현재주차(26주) - log_ymd, week 값을 계산하고, (예: 26-1=25)

join week period는 join_ymd를 써서 가입한 날로부터 이번주차까지의 주차를 계산하고 싶습니다. (예: row=3일 때 52+52+26=130)

 

한번에 질문이 많아서 정리가 조금 어려운데, 혹시 여전히 답변주시기 어려운 경우 현재주차 기준으로 procedure문을 통해 주차별 집계가 될 수 있는 부분만 답변주시면 큰 도움이 될 것 같습니다.

답변에 미리 감사드립니다.

by 마농 [2020.07.07 14:16:34]

주차의 개념에 대한 명확한 정의와 예시가 필요합니다.
2020년 1주차는 몇일부터 몇일까지 인가요?
현재주차가 26주차라는 것은 어떤 기준으로 나온 건가요?
주차의시작이 월요일인지? 일요일인지? 다른 요일인지?, 요일 기준이 아닌지?
년도가 겹치는 구간에 대한 처리 기준이 있는지? 등등.


by 둥둥맨 [2020.07.07 15:06:43]

2020년 1주차는 1월1일~첫 일요일(1/5)까지, 그 뒤로 2주차는 1/6~1/12, ... 형태로 입니다.

주차 시작은 월요일부터이고 요일기준입니다. 연도가 겹치는 구간은 마지막주차를 잘라서 19년 12월 30, 31일을 마지막주로 보고자 합니다. (53주 인거 같네요)


by 마농 [2020.07.07 16:08:40]

그러면 join_ymd 20191223 에 대한 join_week 50 잘못된 예시네요?
규칙대로 한다면 52 주차가 나와야 맞습니다.
실제 데이터가 50 으로 들어 있나요?
현재 주차도 20200707 기준 으로는 26 이 아닌 28 이 나와야 할 것 같네요.


by 마농 [2020.07.07 16:35:36]
WITH t AS
(
SELECT '20200101' log_ymd, 'AAA' id, '20191223' join_ymd, '50' join_week, 'y' col1_yn, '' col2_yn FROM dual
UNION ALL SELECT '20200101', 'AAA', '20191223', '50', '' , 'y' FROM dual
UNION ALL SELECT '20200108', 'AAA', '20191223', '50', 'y', 'y' FROM dual
UNION ALL SELECT '20200109', 'AAA', '20191223', '50', '' , 'y' FROM dual
UNION ALL SELECT '20200101', 'BBB', '20180101', '1' , 'y', 'y' FROM dual
)
SELECT TO_CHAR( log_dt + 3, 'yyyy') log_yyyy
     , (log_dt - sdt) / 7 + 1 log_week
     , id
     , TO_CHAR(join_dt + 3, 'yyyy') join_yyyy
     , (join_dt - join_sdt) / 7 + 1 join_week
     , COUNT(col1_yn) col1_yn_cnt
     , COUNT(col2_yn) col2_yn_cnt
     , (edt -  log_dt) / 7 week_past
     , (edt - join_dt) / 7 join_week_period
  FROM (SELECT log_ymd, id, join_ymd, join_week, col1_yn, col2_yn
             , TRUNC(TO_DATE( log_ymd, 'yyyymmdd'), 'iw')  log_dt
             , TRUNC(TO_DATE(join_ymd, 'yyyymmdd'), 'iw') join_dt
             , TRUNC(TRUNC(TO_DATE(join_ymd, 'yyyymmdd'), 'yy'), 'iw') join_sdt
             , TRUNC(TRUNC(sysdate, 'yy'), 'iw') sdt
             , TRUNC(sysdate, 'iw') edt
          FROM t
         WHERE log_ymd LIKE TO_CHAR(sysdate, 'yyyy')||'%'
        )
 GROUP BY id, log_dt, join_dt, sdt, edt, join_sdt
 ORDER BY id, log_dt, join_dt
;

 


by 둥둥맨 [2020.07.07 17:18:06]

네 52주가 맞는데 잘못된 값이네요. 현재주차는 sysdate 기준으로 뽑았는데 첫주차가 카운트가 안되어서 말씀하신 것 처럼 28주가 되는게 맞는 것 같습니다.
코드 감사드립니다.
1. 이해를 위해 추가질문드리면 yy는 연도추출 (2020년인 경우 20년), iw는 월요일 기준 주차를 쓰는걸로 아는데, sdt와 edt를 TRUNC와 yy, iw를 써서 / 7하게 되면 어떻게 연산이 되는지요?
2. WHERE log_ymd LIKE TO_CHAR(sysdate, 'yyyy')||'%' 문에 대해 설명해주시면 감사하겠습니다.
알려주심에 다시 한번 감사드려요!


by 마농 [2020.07.07 17:39:17]

1. 연산 과정 설명
TRUNC 는 단위에 맞게 잘라내는 함수입니다.
숫자에 적용하면 TRUNC(11.12, 0) = 11, TRUNC(11.12, 1) = 11.1, TRUNC(11.12, -1) = 10
날짜에도 적용 가능합니다.
TRUNC(sysdate, 'yy') = 2020.01.01 (해당 년 1월 1일)
TRUNC(sysdate, 'iw') = 2020.07.06 (해당 주 월요일)
TRUNC(TRUNC(sysdate, 'yy'), 'iw') = 2019.12.30 (1월1일에 해당하는 주의 월요일)
해당년도 첫주차 월요일을 sdt 로 구했습니다.
log_ymd 해당 주 월요일을 log_dt 로 구했습니다.
두개의 월요일끼리 날짜 차이를 7로 나누면 주차가 나오는 것입니다. 첫주가 1주차가 되기 위해 + 1
2. 조건절 설명 : 해당년도 자료만 가져오기 위한 조건입니다.
WHERE log_ymd LIKE TO_CHAR(sysdate, 'yyyy')||'%'
WHERE log_ymd LIKE '2020'||'%'
WHERE log_ymd LIKE '2020%'


by 둥둥맨 [2020.07.07 19:55:39]

많은 공부가 됩니다. 친절한 설명 감사드립니다!

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