안녕하세요.
하루종일 생각했는데 정말 모르겠어서 도움을 요청하고자 글을 올립니다.
아래와 같은 데이블인 경우 조건은
1) 번호와 코드값이 동일한 경우,
2) 각 시행일자를 기준으로 다음에 이어지는 시행일자가 28일 이상 간격이 있는 경우 새로운 행으로 추가하고 싶습니다.
어떻게 쿼리를 짜야할까요?
(기본 데이터)
번호 | 코드 | 시행일자 |
---|---|---|
10 | SEP | 2020-01-01 |
10 | SEP | 2020-01-02 |
10 | SEP | 2020-01-03 |
10 | SEP | 2020-01-04 |
10 | SEP | 2020-02-02 |
10 | SEP | 2020-02-03 |
10 | SEP | 2020-02-04 |
10 | SEP | 2020-02-05 |
10 | SEP | 2020-02-06 |
10 | SEP | 2020-03-07 |
10 | SEP | 2020-03-08 |
10 | SEP | 2020-03-09 |
10 | SEP | 2020-03-10 |
(결과데이터)
1) 결과값으로 3건의 데이터가 추출
2) 시행일자주기(28일간격): 위의 시행일자의 각 데이터를 기준으로 다음일자에 시행되는 데이터가 28일 이상 간격이 있는 경우 새로운 행을 추가한다.
(현재 01-01~01-04 까지는 시행일자가 각 시행일자 기준으로 +1일 간격이나
01-04일을 기준으로 02-02 일은 28일 이상 간격이 있으므로 새로운 행을 추가하고 주기를 구분합니다.)
3) 더불어 28일 간격으로 데이터가 나눠지므로 하나의 데이터에 총 몇번을 시행했는지 count를 하고 싶습니다.
번호 | 코드 | 시행일자주기(28일간격) | 주기별연속된데이터(시행건수) | |
---|---|---|---|---|
10 | SEP | 1 | 4 | |
10 | SEP | 2 | 5 | |
10 | SEP | 3 | 4 |
제발 도와주세요,
WITH T AS ( SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-01-01') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-01-02') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-01-03') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-01-04') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-02-02') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-02-03') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-02-04') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-02-05') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-02-06') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-03-07') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-03-08') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-03-09') DT UNION ALL SELECT '10' NO, 'SEP' CD, CONVERT(DATE,'2020-03-10') DT ) SELECT NO, CD, ROW_NUMBER() OVER(ORDER BY GB) RN, COUNT(1) CNT FROM ( SELECT NO, CD, SUM(FG) OVER (PARTITION BY NO, CD ORDER BY DT) GB FROM ( SELECT NO, CD, DT , CASE WHEN DATEDIFF(DAY, LAG(DT) OVER(PARTITION BY NO, CD ORDER BY DT), DT) >= 28 THEN 1 ELSE 0 END FG FROM T ) S1 ) S2 GROUP BY NO, CD, GB
WITH t AS ( SELECT 10 no, 'SEP' cd, '2020-01-01' dt UNION ALL SELECT 10, 'SEP', '2020-01-02' UNION ALL SELECT 10, 'SEP', '2020-01-03' UNION ALL SELECT 10, 'SEP', '2020-01-04' UNION ALL SELECT 10, 'SEP', '2020-02-02' UNION ALL SELECT 10, 'SEP', '2020-02-03' UNION ALL SELECT 10, 'SEP', '2020-02-04' UNION ALL SELECT 10, 'SEP', '2020-02-05' UNION ALL SELECT 10, 'SEP', '2020-02-06' UNION ALL SELECT 10, 'SEP', '2020-03-07' UNION ALL SELECT 10, 'SEP', '2020-03-08' UNION ALL SELECT 10, 'SEP', '2020-03-09' UNION ALL SELECT 10, 'SEP', '2020-03-10' ) SELECT no, cd, grp , COUNT(*) cnt FROM (SELECT no, cd, dt , SUM(flag) OVER(PARTITION BY no, cd ORDER BY dt) grp FROM (SELECT no, cd, dt , CASE WHEN DATEDIFF(day, LAG(dt) OVER(PARTITION BY no, cd ORDER BY dt), dt) < 28 THEN 0 ELSE 1 END flag FROM t ) a ) a GROUP BY no, cd, grp ;