database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40657 게시물 읽기
No. 40657
해당월을 입력받아 주별데이터 합계 구하는 쿼리 문의
작성자
마스
작성일
2014-12-22 17:18
조회수
7,891

SELECT Z.*

, ROUND(X_TOTAMT/X_BILL) AS X_CUSTOMER

FROM ( SELECT TO_CHAR(TO_DATE(X_DATE), 'YYYY-MM') AS X_MONTH

, COUNT(X_BILL) AS X_BILL

, SUM(TH_TOTAMT) AS X_TOTAMT

, TO_NUMBER(SUM(X_TOTAMT)-SUM(TH_DCAMT)) AS X_SALES

, SUM(TH_DCAMT) AS TH_DCAMT

, SUM(TH_CASH) AS TH_CASH

, SUM(TH_FOOD) AS TH_FOOD

FROM X_SALE

WHERE X_DATE LIKE '%201411%'

GROUP BY X_DATE

ORDER BY X_DATE);

 

 

이략 이런 구조의 테이블이 있는데요 월을 입력 받아서 그 월의 해당 주차 1주, 2주, 3주, 4주의 데이터별로 합계를 구하는 쿼리를

 

짜야 하는데 어떻게 해야 할지 몰라서 질문 올립니다. 아시는분 계시면 답변좀 부탁드립니다.

 

X_DATE 컬럼에는 YYYYMMDD형태로 데이터가 들어 갑니다. 20141222 이런식으로요. 그리고 해당 주차에 데이터가 없어도 구할 수 있는

 

쿼리 였으면 합니다. 이걸로 삽질 길게 하네요.ㅠㅠ

이 글에 대한 댓글이 총 17건 있습니다.

주차를 나누는 기준에 대한 설명이 없네요.

마농(manon94)님이 2014-12-22 18:20에 작성한 댓글입니다.

주차는 해당월이 시작되는 일요일 부터 토요일 까지 입니다.

마스님이 2014-12-22 18:25에 작성한 댓글입니다.
이 댓글은 2014-12-22 18:29에 마지막으로 수정되었습니다. Edit

SELECT x.ym
     , x.w
     , x_bill
     , x_totamt
     , x_sales
     , th_dcamt
     , th_cash
     , th_food
     , ROUND(x_totamt / x_bill) AS x_customer
  FROM (SELECT TO_CHAR(
               TRUNC(TO_DATE(x_date, 'yyyymmdd'), 'd')
               , 'yyyymmdd') sdt
             , COUNT(x_bill)                 AS x_bill
             , SUM(th_totamt)                AS x_totamt
             , SUM(x_totamt) - SUM(TH_DCAMT) AS x_sales
             , SUM(th_dcamt)                 AS th_dcamt
             , SUM(th_cash)                  AS th_cash
             , SUM(th_food)                  AS th_food
          FROM x_sale
         WHERE x_date LIKE '%'||'201411'||'%'
         GROUP BY TRUNC(TO_DATE(x_date, 'yyyymmdd'), 'd')
        ) z
     , (SELECT TO_CHAR(ym, 'yyyy-mm') ym
             , LEVEL w
             , TO_CHAR(TRUNC(ym, 'd') + (LEVEL - 1) * 7, 'yyyymmdd') sdt
          FROM (SELECT TO_DATE('201411', 'yyyymm') ym FROM dual)
         CONNECT BY LEVEL <= (TRUNC(LAST_DAY(ym), 'd') - TRUNC(ym, 'd'))
                             / 7 + 1
        ) x
 WHERE x.sdt = z.sdt(+)
;

마농(manon94)님이 2014-12-22 20:06에 작성한 댓글입니다.
이 댓글은 2014-12-22 20:08에 마지막으로 수정되었습니다.

답변 감사합니다. 한가지 더 물어보고 싶은 부분은 11월달을 예로 들어서 지금 6주차 데이터가 나오고 있는데요. 11월달이 시작하는 일요일 그러니깐

 

2일부터 8일

9일부터 15일

16일부터 22일

23일부터 29일

30일부터 6일까지의 데이터로 뽑을려면 어떻게 진행을 해야 하나요?ㅠ

마스님이 2014-12-23 09:28에 작성한 댓글입니다. Edit

그럼 11월1일은 어쩌구요? 버리는 건가요?

그런 식이라면? 11월30일도 버려야 하는 것 아닌지?

그리고, 12월은 어떻게 되는 건가요?

12월 1일~6일이 첫주인가요? 아니면 버려지는 주인가요?

아니면 전월인 11월 마지막주에 포함되어야 하는 건가요?

포함되어야 한다면? 201411월 조건으로 검색시 조회구간은?

11월2일 ~ 12월 6일 인 건가요?

마농(manon94)님이 2014-12-23 09:39에 작성한 댓글입니다.
이 댓글은 2014-12-23 09:47에 마지막으로 수정되었습니다.

이부분에 대해서는 정확하게 협의후에 다시 질문을 올려야 될것 같네요.ㅠ

마스님이 2014-12-23 09:58에 작성한 댓글입니다. Edit

조회하는 달의 첫번째 일요일의 첫주의 시작이고 그달이 일요일로 끝나면 그다음달 토요일까지 조회가 가능 해야 하네요.

마농님 말대로 조회구간은 11월2일부터 12월6일까지 입니다.

 

 

마스님이 2014-12-23 10:24에 작성한 댓글입니다. Edit

SELECT x.ym
     , x.w
     , x_bill
     , x_totamt
     , x_sales
     , th_dcamt
     , th_cash
     , th_food
     , ROUND(x_totamt / x_bill) AS x_customer
  FROM (SELECT TO_CHAR(
               TRUNC(TO_DATE(x_date, 'yyyymmdd'), 'd')
               , 'yyyymmdd') sdt
             , COUNT(x_bill)                 AS x_bill
             , SUM(th_totamt)                AS x_totamt
             , SUM(x_totamt) - SUM(TH_DCAMT) AS x_sales
             , SUM(th_dcamt)                 AS th_dcamt
             , SUM(th_cash)                  AS th_cash
             , SUM(th_food)                  AS th_food
          FROM x_sale
         WHERE x_date >= TO_CHAR(
                         NEXT_DAY(TO_DATE('201411', 'yyyymm')-1, 1)
                         , 'yyyymmdd')
           AND x_date <= TO_CHAR(
                         TRUNC(LAST_DAY(TO_DATE('201411', 'yyyymm')), 'd') + 6
                         , 'yyyymmdd')
         GROUP BY TRUNC(TO_DATE(x_date, 'yyyymmdd'), 'd')
        ) z
     , (SELECT TO_CHAR(ym, 'yyyy-mm') ym
             , LEVEL w
             , TO_CHAR(NEXT_DAY(ym-1, 1) + (LEVEL-1) * 7, 'yyyymmdd') sdt
          FROM (SELECT TO_DATE('201411', 'yyyymm') ym FROM dual)
         CONNECT BY LEVEL <= ( TRUNC(LAST_DAY(ym), 'd')
                             - NEXT_DAY(ym-1, 1)
                             ) / 7 + 1
        ) x
 WHERE x.sdt = z.sdt(+)
;

마농(manon94)님이 2014-12-23 11:34에 작성한 댓글입니다.

감사합니다. 꾸벅~ㅎ

 

마지막으로 한가지만 더 여쭤 볼께요. 대비기간별 비교를 할려고 하는데 union all

 

을 사용해서 하면 될까요?

 

그리고 조회한달 총합이랑 주별 평균을 낼려고 하는데 어떤 식으로 해야하는지도

 

막막하네요.ㅠ

 

예를 들어 x_totamt값이 한달총 합이 100이고 1주차가 20 2주차가 40 3주차가 40 이고 나머지 주차는 0일때 총합100에 대한 주별 평균 값을 구하고 싶습니다.

마스님이 2014-12-23 12:24에 작성한 댓글입니다. Edit

결과 예시를 말로 설명하지 마시고 표로 보여주세요.

마농(manon94)님이 2014-12-23 12:31에 작성한 댓글입니다.

 

 주별     조회기간    대비기간  성장율
합계 비율     합계 비율      대비기간에 비해 조회기간이 몇%성장 혹은 적자
 1주 20  20%     50 50%   
 2주  20  20%    50  50%  
 3주  20  20%    0  0%  
 4주  20  20%    0  0%  
 5주  20  20%    0  0%  

조회기간은 2014년 11월 대비기간은 2014년 12월

마스님이 2014-12-23 12:56에 작성한 댓글입니다. Edit

구하고자 하는 것이 특정월 기준 전월 대비 증감표 인가요?

아니면 꼭 전월이 아닌 임의의 두개 월을 비교하는 건가요?

마농(manon94)님이 2014-12-23 13:32에 작성한 댓글입니다.

임의의 두개 월을 비교하는 거예요

마스님이 2014-12-23 13:52에 작성한 댓글입니다.
이 댓글은 2014-12-23 13:53에 마지막으로 수정되었습니다. Edit

WITH x_sale AS
(-- 원본 테이블 --
SELECT '20141102' x_date, 20 v FROM dual
UNION ALL SELECT '20141109', 20 FROM dual
UNION ALL SELECT '20141116', 20 FROM dual
UNION ALL SELECT '20141123', 20 FROM dual
UNION ALL SELECT '20141130', 20 FROM dual
UNION ALL SELECT '20141207', 50 FROM dual
UNION ALL SELECT '20141214', 50 FROM dual
)
, x_code AS
(-- 검색 기간 조건 --
SELECT gb, w
     , TO_CHAR(NEXT_DAY(ym - 1, 1) + w * 7 - 7, 'yyyymmdd') sdt
     , TO_CHAR(NEXT_DAY(ym - 1, 1) + w * 7 - 1, 'yyyymmdd') edt
  FROM (SELECT 1 gb, TO_DATE('201411', 'yyyymm') ym FROM dual
        UNION ALL SELECT 2, TO_DATE('201412', 'yyyymm') FROM dual
        )
     , (SELECT LEVEL w FROM dual CONNECT BY LEVEL <= 5)
 WHERE w <= (TRUNC(LAST_DAY(ym), 'd') - NEXT_DAY(ym - 1, 1)) / 7 + 1
)
SELECT a.w
     , SUM(DECODE(a.gb, 1, b.v)) v1
     , RATIO_TO_REPORT(SUM(DECODE(a.gb, 1, b.v))) OVER() * 100 r1
     , SUM(DECODE(a.gb, 2, b.v)) v2
     , RATIO_TO_REPORT(SUM(DECODE(a.gb, 2, b.v))) OVER() * 100 r2
     , SUM(DECODE(a.gb, 2, b.v)) - SUM(DECODE(a.gb, 1, b.v)) AS 증감값
     , NVL   (SUM(DECODE(a.gb, 2, b.v)), 0)
     / NULLIF(SUM(DECODE(a.gb, 1, b.v)), 0) * 100 AS 증감율
  FROM x_code a
     , x_sale b
 WHERE b.x_date(+) BETWEEN a.sdt AND a.edt
 GROUP BY a.w
 ORDER BY w
;

마농(manon94)님이 2014-12-23 14:16에 작성한 댓글입니다.

정말 감사합니다.~ㅎㅎ 원하던 대로 데이터가 나왔네요ㅎㅎ

 

저 근데 증감율 구하는 곳에서 증가율은 나오는데 감소율은 0으로만 나오네요.ㅠ

 

0으로 나누니깐 발생하는 문제인데 이부분은 어떻게 해결을 해야 할까요?

마스님이 2014-12-23 15:10에 작성한 댓글입니다. Edit

WITH x_sale AS
(-- 원본 테이블 --
SELECT '20141102' x_date, 20 v FROM dual
UNION ALL SELECT '20141109', 20 FROM dual
UNION ALL SELECT '20141116', 20 FROM dual
--UNION ALL SELECT '20141123', 20 FROM dual -- 주석
UNION ALL SELECT '20141130', 20 FROM dual
UNION ALL SELECT '20141207', 50 FROM dual
UNION ALL SELECT '20141214', 50 FROM dual
UNION ALL SELECT '20141228', 25 FROM dual -- 추가
)
, x_code AS
(-- 검색 기간 조건 --
SELECT gb, w
     , TO_CHAR(NEXT_DAY(ym - 1, 1) + w * 7 - 7, 'yyyymmdd') sdt
     , TO_CHAR(NEXT_DAY(ym - 1, 1) + w * 7 - 1, 'yyyymmdd') edt
  FROM (SELECT 1 gb, TO_DATE('201411', 'yyyymm') ym FROM dual
        UNION ALL SELECT 2, TO_DATE('201412', 'yyyymm') FROM dual
        )
     , (SELECT LEVEL w FROM dual CONNECT BY LEVEL <= 5)
 WHERE w <= (TRUNC(LAST_DAY(ym), 'd') - NEXT_DAY(ym - 1, 1)) / 7 + 1
)
SELECT w
     , v1
     , ROUND(RATIO_TO_REPORT(v1) OVER() * 100, 2) r1
     , v2
     , ROUND(RATIO_TO_REPORT(v2) OVER() * 100, 2) r2
     , (v2 - v1) AS 증감값
     , ROUND((v2 - v1) / NULLIF(v1, 0) * 100, 2) AS 증감율
  FROM (SELECT a.w
             , NVL(SUM(DECODE(a.gb, 1, b.v)), 0) v1
             , NVL(SUM(DECODE(a.gb, 2, b.v)), 0) v2
          FROM x_code a
             , x_sale b
         WHERE b.x_date(+) BETWEEN a.sdt AND a.edt
         GROUP BY a.w
        )
 ORDER BY w
;

마농(manon94)님이 2014-12-23 15:23에 작성한 댓글입니다.

감사합니다~ 정말 많은 도움이 되었습니다.

마스님이 2014-12-23 17:30에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
40661ERWIN Reverse Engineer 기능 문의입니다. [2]
최보현
2014-12-23
7813
40660패키지가 실행이 안되네요 [1]
뉴비
2014-12-23
6620
40658세로결과를 가로 고정column으로 출력 방법 부탁드립니다. [2]
jinkuidong
2014-12-22
7120
40657해당월을 입력받아 주별데이터 합계 구하는 쿼리 문의 [17]
마스
2014-12-22
7891
40656import 에러발생 도와주세요.. [1]
엠제이준
2014-12-22
8830
40655statement trigger 에서 변경된 데이터 확인 방법 [3]
뉴비
2014-12-20
6521
40654Oracle 9i DB 복구방법 [1]
박태학
2014-12-19
6492
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.026초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다