SELECT NVL(TO_CHAR(dtime, 'yyyymmdd'), '전체') dt , COUNT(*) tot , COUNT(DECODE(product, '상품A', 1)) 상품A , COUNT(DECODE(product, '상품B', 1)) 상품B , COUNT(DECODE(product, '상품C', 1)) 상품C FROM t WHERE dtime >= TO_DATE('20120620', 'yyyymmdd') AND dtime < TO_DATE('20120701', 'yyyymmdd') + 1 GROUP BY ROLLUP(TO_CHAR(dtime, 'yyyymmdd')) ;
SELECT NVL(a.dt, '전체') 날짜 , NVL(SUM(b.tot), 0) tot , NVL(SUM(b.상품A), 0) 상품A , NVL(SUM(b.상품B), 0) 상품B , NVL(SUM(b.상품C), 0) 상품C FROM (SELECT TO_CHAR(TO_DATE('20120620', 'yyyymmdd') + LEVEL - 1, 'yyyymmdd') dt FROM dual CONNECT BY LEVEL <= TO_DATE('20120701', 'yyyymmdd') - TO_DATE('20120620', 'yyyymmdd') + 1 ) a , (SELECT TO_CHAR(dtime, 'yyyymmdd') dt , COUNT(*) tot , COUNT(DECODE(product, '상품A', 1)) 상품A , COUNT(DECODE(product, '상품B', 1)) 상품B , COUNT(DECODE(product, '상품C', 1)) 상품C FROM t WHERE dtime >= TO_DATE('20120620', 'yyyymmdd') AND dtime < TO_DATE('20120701', 'yyyymmdd') + 1 GROUP BY TO_CHAR(dtime, 'yyyymmdd') ) b WHERE a.dt = b.dt(+) GROUP BY ROLLUP(a.dt) ;
달력 테이블을 미리 만들어 두시고 사용하시면 편리합니다.
MySQL 달력 만들기 : http://www.gurubee.net/article/65315
SELECT IFNULL(a.dt, '전체') 날짜 , IFNULL(SUM(b.tot), 0) tot , IFNULL(SUM(b.상품A), 0) 상품A , IFNULL(SUM(b.상품B), 0) 상품B , IFNULL(SUM(b.상품C), 0) 상품C FROM (SELECT dt FROM 달력테이블 WHERE dt >= '20120620' AND dt <= '20120701' ) a LEFT OUTER JOIN (SELECT DATE_FORMAT(dtime, '%Y%m%d') dt , COUNT(*) tot , COUNT(CASE product WHEN '상품A' THEN 1 END) 상품A , COUNT(CASE product WHEN '상품B' THEN 1 END) 상품B , COUNT(CASE product WHEN '상품C' THEN 1 END) 상품C FROM t WHERE dtime >= CAST('20120620' AS DATE) AND dtime < CAST('20120701' AS DATE) + INTERVAL 1 DAY GROUP BY DATE_FORMAT(dtime, '%Y%m%d') ) b ON a.dt = b.dt GROUP BY a.dt WITH ROLLUP ;
제가 하려는 작업은 para_value 라는 컬럼과 그 컬럼의 카운트, 날짜를 조회하고 싶은 건데요.
일단 데이터가 아래와 같다고 가정했을 경우.. ( reg_date 형식은 date 이며 년/월/일 까지만 나옵니다 )
para_value | reg_date |
test | 18/03/06 |
test | 18/03/06 |
test123 | 18/03/06 |
test | 18/03/06 |
test123 | 18/03/06 |
apeach | 18/03/06 |
test123 | 18/03/07 |
apeach | 18/03/07 |
test | 18/03/07 |
제가 위에 댓글을 참고하여 짠 쿼리는 아래와 같습니다...
SELECT NVL(TO_CHAR(REG_DATE, 'YYYY-MM-DD'), '전체') AS REG_DATE, COUNT(PARA_VALUE) AS CNT, PARA_VALUE FROM EXT_IN WHERE REG_DATE between TO_DATE('2018-03-06', 'YYYY-MM-DD') and TO_DATE('2018-03-06', 'YYYY-MM-DD')+1 GROUP BY rollup(to_char(REG_DATE,'YYYY-MM-DD')),PARA_VALUE ;
제가 보고 싶은 데이터는...
3월 6일로 조건을 주어 검색했을 경우 아래와 같이 결과가... 나왔으면 하는 바람입니다.... rollup이라는 조건?을 없애면... 실행이 안되더라구요.....
제발 도와주세요 ㅠㅠㅠㅠㅠㅠ
reg_date | cnt | para_value |
2018-03-06 | 2 | test123 |
2018-03-06 | 3 | test |
2018-03-06 | 1 | apeach |
아 그리고 where 절에 있는 between 조건은 저렇게 사용하면 되는게 맞을까요...?
where 절에 있는 날짜 부분은 jsp에서 문자열로 넘어옵니다... 2018-03-06 이런 식으로요...
아 그리고 날짜가 만약 2018-03-01~2018-03-31 이라면 날짜순으로 출력되었으면 좋겠는데..
그 조건은 어디에 주어야 하나요..?
SELECT TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE, COUNT(PARA_VALUE) AS CNT, PARA_VALUE FROM EXT_IN WHERE REG_DATE between TO_DATE('2018-03-06', 'YYYY-MM-DD') and TO_DATE('2018-03-06', 'YYYY-MM-DD')+1 GROUP BY (to_char(REG_DATE,'YYYY-MM-DD')),PARA_VALUE order by REG_DATE desc
이 쿼리로 원하는 데이터가 나오는 것 까지는 해결 했습니다! !!!!~~~~~~~~
그런데 between은 저렇게 사용하는게 맞는건가요..?
between 조건은 시작, 종료 조건 모두 등호(=)가 포함됩니다.
+ 1 을 사용하려면 등호가 빠져야 하고 등호가 포함되려면 + 0.99999 를 써야 합니다.
para_value 에 널이 없다면? 굳이 count(para_value) 할 이유 없습니다.
정렬기준은 중복되는 날짜만으로 하는 것 보다는 유니크한 조건을 추가해 주는 게 좋습니다.
질문은 댓글로 다는 것보다 새로 등록해 주시는게 좋을 듯 하네요.
SELECT TO_CHAR(reg_date, 'yyyy-mm-dd') AS reg_date , COUNT(*) AS cnt , para_value FROM ext_in WHERE reg_date BETWEEN TO_DATE('2018-03-06', 'yyyy-mm-dd') AND TO_DATE('2018-03-06', 'yyyy-mm-dd') + 0.99999 GROUP BY TO_CHAR(reg_date, 'yyyy-mm-dd'), para_value ORDER BY reg_date DESC, para_value ; SELECT TO_CHAR(reg_date, 'yyyy-mm-dd') AS reg_date , COUNT(*) AS cnt , para_value FROM ext_in WHERE reg_date >= TO_DATE('2018-03-06', 'yyyy-mm-dd') AND reg_date < TO_DATE('2018-03-06', 'yyyy-mm-dd') + 1 GROUP BY TO_CHAR(reg_date, 'yyyy-mm-dd'), para_value ORDER BY reg_date DESC, para_value ;