날짜(기간)별 합계 1 5 1,796

by 흔들린우동 SQL Query 오라클 날짜 [2021.03.27 13:18:12]


안녕하세요.

아무리 고민을 해도 답이 나오지 않아서 문의 드립니다.

1. 날짜는 한달단위로 표시가 됩니다.

--> 해당월의 1일부터 마지일까지 출력하는 부분은 완성했습니다.

2. 현재 데이터는 시작일, 종료일로 입력되어 있습니다.

3. 날짜(1달 단위)에 시작일, 종료일이 포함된 데이터 건수를 가져와야 합니다.

현재 등록되어 있는 데이터는 아래와 같습니다.

번호     시작일                종료일

1       2021.03.02       2021.03.04

2      2021.03.04        2021.03.05

3.     2021.03.05        2021.03.06

 

데이터가 위와 같이 입력되어 있을경우 출력데이터가 해당월 전체일자(1달 단위)가 출력되고 시작일, 종료일에 포함된 날짜에 카운트를 구해야  합니다.

기준일자           카운트

2021.03.01      0

2021.03.02       1

2021.03.03       1

2021.03.04       2

2021.03.05      2

2021.03.06      1

2021.03.07      0 

2021.03.08     0

......

*기준일자에 시작일 종료일이  포함된 데이터 건수를 가져와야 하는데 아무리 고민을 해도 어떻게 할수 있을지 모르겠습니다.

도움 부탁드립니다..

 

by pajama [2021.03.27 17:36:07]

달력테이블과 조인하는 방법을 참고해봤습니다.

http://www.gurubee.net/article/55635

http://www.gurubee.net/article/67721

 

WITH CALENDAR_DATES AS (  
  SELECT DATE'2021-02-28' + LEVEL CALENDAR_DATE   
  FROM   DUAL  
  CONNECT BY LEVEL <= 10
),
TMP AS (
SELECT SDT + (LV - 1) DT
  FROM (SELECT 1 NUM, TO_DATE('2021.03.02','YYYY.MM.DD') SDT, TO_DATE('2021.03.04','YYYY.MM.DD') EDT FROM DUAL UNION ALL
        SELECT 2, TO_DATE('2021.03.04','YYYY.MM.DD'), TO_DATE('2021.03.05','YYYY.MM.DD') FROM DUAL UNION ALL
        SELECT 3, TO_DATE('2021.03.05','YYYY.MM.DD'), TO_DATE('2021.03.06','YYYY.MM.DD') FROM DUAL)
     , (SELECT LEVEL LV
          FROM DUAL
       CONNECT BY LEVEL <= 10)
 WHERE LV <= EDT + 1 - SDT
 ORDER BY DT
)
SELECT CALENDAR_DATE, COUNT(T.DT)
FROM CALENDAR_DATES 
LEFT JOIN TMP T
ON T.DT = CALENDAR_DATE
GROUP BY CALENDAR_DATE
ORDER BY CALENDAR_DATE

 


by 뉴비디비 [2021.03.28 13:23:28]

pajama님 쿼리 참고해서 약간 심플버전(?) 입니다.

WITH dataTbl AS (
    SELECT 1 AS nums,  TO_DATE('2021.03.02','YYYY.MM.DD') AS sdate , TO_DATE('2021.03.04','YYYY.MM.DD') AS edate FROM dual UNION ALL
    SELECT 2 AS nums,  TO_DATE('2021.03.04','YYYY.MM.DD') AS sdate , TO_DATE('2021.03.05','YYYY.MM.DD') AS edate FROM dual UNION ALL
    SELECT 3 AS nums,  TO_DATE('2021.03.05','YYYY.MM.DD') AS sdate , TO_DATE('2021.03.06','YYYY.MM.DD') AS edate FROM dual
) 
,CALENDAR_DATES AS (  
    SELECT 
        TO_DATE('2021-02-28','YYYY.MM.DD') + LEVEL CALENDAR_DATE   
    FROM DUAL
    CONNECT BY LEVEL <= 8
)

SELECT
    A.CALENDAR_DATE AS check_date, COUNT(nums) AS date_cnt -- , MIN(B.sdate), MAX(B.edate) 
FROM CALENDAR_DATES A
    LEFT OUTER JOIN dataTbl B ON A.CALENDAR_DATE BETWEEN B.sdate AND B.edate
GROUP BY A.CALENDAR_DATE
ORDER BY A.CALENDAR_DATE

 


by pajama [2021.03.28 16:53:38]

뉴비디비님 쿼리가 행복제가 적어서 좋아보입니다~


by 마농 [2021.03.29 10:14:55]
WITH t AS
(
SELECT 1 no, '2021.03.02' sdt, '2021.03.04' edt FROM dual
UNION ALL SELECT 2, '2021.03.04', '2021.03.05' FROM dual
UNION ALL SELECT 3, '2021.03.05', '2021.03.06' FROM dual
)
, calendar AS
(
SELECT TO_CHAR(dt + LEVEL - 1, 'yyyy.mm.dd') dt
  FROM (SELECT TO_DATE('202103', 'yyyymm') dt FROM dual)  -- 기준년월
 CONNECT BY LEVEL <= LAST_DAY(dt) - dt + 1
)
SELECT a.dt
     , COUNT(b.sdt) cnt
  FROM calendar a
  LEFT OUTER JOIN t b
    ON a.dt BETWEEN b.sdt AND b.edt
 GROUP BY a.dt
 ORDER BY a.dt
;

 


by 흔들린우동 [2021.04.02 21:20:20]

모두 답글 달아주셔서 감사합니다.

고맙단 말을 진작 드렸어야 하는데 일이바쁘다 보니, 감사하다는 말이 늦었네요.

날짜를 beteen 문으로 걸어서 count 하는 부분은 아직도 제가 이해가 잘 안되네요.

실력이 미천하다보니 어떻게 저렇게 했는데 결과가 나오는지....... ㅠㅠ

저는 캘린더 외에도 시작일과 종료일도 level과 connect by로 날짜를 일자별로 생성한뒤, count하는 방법을 썼는데, 그러다 보니 데이터가 많아지면 속도가 무지하게 느려지는 현상이 발생했습니다.

덕분에 많이 배우고 갑니다.

모두 감사드립니다.

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