그룹함수 GROUPING_ID
저번 글의

마지막..


SELECT NVL(company_cd,'*') as company_cd ,
             NVL(customer_cd,'*') as customer_cd ,  
            '200612'                      as tran_date ,
            NVL(subject,'*')          as subject,
           sum(amt)                    as amt
  FROM t_darkneo
 GROUP BY ROLLUP ( company_cd , customer_cd ,  subject );
결과;


COMPANY_CD CUSTOMER_CD TRAN_DATE SUBJECT    AMT                   
---------- ----------- --------- ---------- ----------------------
11111      77777       200612    AAA         200                   
11111      77777       200612    *              200                   
11111      88888       200612    BBB         400                   
11111      88888       200612    *              400                   
11111      99999       200612    AAA         100                   
11111      99999       200612    BBB         200                   
11111      99999       200612    *             300                   
11111      *             200612    *             900                   
22222      99999       200612    CCC        900                   
22222      99999       200612    *             900                   
22222      *             200612    *             900                   
*             *            200612    *             1800  

12 rows selected

저번글의 마지만 문제? 는

*             *            200612    *             1800 
총 합계 금액이 나오는 문제가 나오지 .. 이런 데이터를 제거 하기 위해서는 -_-?

HAVING company_cd <>  '*' <- 요렇게 해도 물론 결과는 나오지...만,,

흠흠..이런걸 원하는게 아니잖아..^^  '*'  조건이 두개이상 인 경우도 있고..ㅎㅎ

각 단계의 별로 어떤 기준으로 Grouping 했다는 정보도 필요할 경우도 있고..ㅎㅎ

그래서 만들어진(?) 함수 GROUPING_ID

사용해보자..
아..역시나 함수정의나 보다 자세한 설명은 다른 인터넷을 이용해주길..-_-;

SELECT NVL(company_cd,'*') as company ,
             NVL(customer_cd,'*')as customer, 
             '200612'           as tran_date , 
             NVL(subject,'*')    as subject,
             sum(amt) as amt ,
             GROUPING_ID( company_cd , customer_cd ,  subject) as depth_level
  FROM   t_darkneo
 GROUP BY ROLLUP ( company_cd , customer_cd ,  subject )

COMPANY    CUSTOMER   TRAN_DATE SUBJECT    AMT                    DEPTH_LEVEL           
---------- ---------- --------- ---------- ---------------------- ----------------------
11111      77777      200612    AAA         200                    0                     
11111      77777      200612    *             200                    1                     
11111      88888      200612    BBB         400                    0                     
11111      88888      200612    *             400                    1                     
11111      99999      200612    AAA        100                    0                     
11111      99999      200612    BBB        200                    0                     
11111      99999      200612    *            300                    1                     
11111      *            200612    *            900                     3                     
22222      99999      200612    CCC       900                     0                     
22222      99999      200612    *            900                      1                     
22222      *            200612    *            900                      3                     
*            *            200612    *            1800                    7                     

12 rows selected

DEPTH_LEVEL   이라는 컬럼 값의 보면..
0 , 1 , 3 , 7 이렇게 값이  나오잖아..?  무슨 뜻일까? ㅋㅋ
여기서부터는 나의 추측?생각이지만,
-----------------------------------------------------------------------------
컴퓨터는 알다시피 이진수를 사용하지? 그 이진수를 이용해서 각 Level의 Depth를
표현한거 같아!
즉.. 3개의 레벨을 이진수로 표현한다면 ,
이진수 000  은 최하 레벨
이진수 111  은 최고 레벨
이겠지?

------------------------------------------------------------------------------
다시 돌아와서..다시 DEPTH_LEVEL 의 값들을 살펴보도록 하자

아! 라는 감탄사 가 나오냐?? ㅋㅋ

'*' 가 하나도 없는 녀석들은 전부다 0 이지?
즉 최하 레벨 GROUP BY 로 해석한다면 GROUP BY ( company_cd , customer_cd ,  subject )
전부 '*' 인 녀석은 7로 최고 레벨..
GROUP BY  조건없이 즉..전체의 총합이라는 애기

ROLLUP 의 조건이
  GROUP BY ROLLUP ( company_cd , customer_cd ,  subject )
즉.3가지 조건이 니깐 이진수 000 =7 최고 레벨이라는 뜻;!


자..다시 좀 더 이쁘게 쿼리를 만들어 보자 ..


SELECT NVL(company_cd,'*') as company ,
             NVL(customer_cd,'*')as customer, 
             '200612'           as tran_date , 
             NVL(subject,'*')    as subject,
             sum(amt) as amt ,
            CASE GROUPING_ID( company_cd , customer_cd ,  subject)
                 WHEN 0 THEN 'date별 합계'
                 WHEN 1 THEN 'date,Subject별 합계'
                 WHEN 3 THEN 'date,Subject,customer_cd 별 합계'
                 WHEN 7 THEN '총 합계'
                 ELSE NULL
            END  as depth_level
  FROM t_darkneo
 GROUP BY ROLLUP ( company_cd , customer_cd ,  subject )
결과.

COMPANY    CUSTOMER   TRAN_DATE SUBJECT    AMT                    DEPTH_LEVEL                  
---------- ---------- --------- ---------- ---------------------- -----------------------------
11111      77777      200612    AAA     200            date별 합계                  
11111      77777      200612    *          200            date,Subject별 합계          
11111      88888      200612    BBB      400            date별 합계                  
11111      88888      200612    *          400            date,Subject별 합계          
11111      99999      200612    AAA     100            date별 합계                  
11111      99999      200612    BBB      200            date별 합계                  
11111      99999      200612    *          300            date,Subject별 합계          
11111      *            200612    *          900            date,Subject,customer_cd 별 합계
22222      99999      200612    CCC     900            date별 합계                  
22222      99999      200612    *          900            date,Subject별 합계          
22222      *            200612    *          900            date,Subject,customer_cd 별 합계
*            *            200612    *          1800           총 합계                      

12 rows selected
음..별로 이쁘게 안되네..

이렇게 GROUPING_ID 을 이용하면 각 Level 의 Depth 를 알수있으니깐.
필요하지 않는 단계를 제거 할수 있겠지??

제거 하는것은...귀찮으니 패스 -_-;

아.물론 이쿼리도 개선할 부분이 무궁무궁 하지만 ..-_-
일단 가장 귀찮은 부분이 어디일까?

생각하시오 -_-;;

생각..생각..
.
.

모..역시 정답 이라고 할수는 없지만,

            CASE GROUPING_ID( company_cd , customer_cd ,  subject)
                 WHEN 0 THEN 'date별 합계'
                 WHEN 1 THEN 'date,Subject별 합계'
                 WHEN 3 THEN 'date,Subject,customer_cd 별 합계'
                 WHEN 7 THEN '총 합계'
                 ELSE NULL
            END  as depth_level

이부분이겠지?

이거는 일종의 Tip 인데
GROUPING_ID 의 값이 이진수 값인거는 알고 있고.. 지금 쿼리에서는
단계가 세단계 뿐이라서 Max 7 에 Min 0 인 값이 니깐..
직접 0 , 1 ,3 , 7 이라고 적었지만..
단계가 10단계 라면? 2의 10승은 1024 -_- 는 간단하게 되지만 ,
2의 14 승은? 그런 귀차니즘을.. 극복??? 하기 위해서 만들어진 함수

BIN_TO_NUM
이 함수는 함수 설명 그래도 2진수를 10진수로 바꾸어주는 훌륭한 함수다 -_-;

BIN_TO_NUM(1,1,1) = 7  , BIN_TO_NUM(0,0,1 ) = 1
을 리턴하지!!

이제 감이 팍팍 오냐?? ^^

좀전의 쿼리를 다시 정리하면,


SELECT '200612'           as tran_date , 
             NVL(company_cd,'*') as company ,
             NVL(customer_cd,'*')as customer, 
            NVL(subject,'*')    as subject,
            sum(amt) as amt ,
           CASE GROUPING_ID( company_cd , customer_cd ,  subject)
                WHEN BIN_TO_NUM(0,0,0) THEN 'date별 합계'
                WHEN BIN_TO_NUM(0,0,1) THEN 'date,Subject별 합계'
                WHEN BIN_TO_NUM(0,1,1) THEN 'date,Subject,customer_cd 별 합계'
                WHEN BIN_TO_NUM(1,1,1) THEN '총 합계'
                ELSE NULL
           END  as depth_level
FROM   t_darkneo
GROUP BY ROLLUP ( company_cd , customer_cd ,  subject )

결과는 같으니깐 생략.... 그래도 한번 해주는 센스 필요..=ㅁ=;
아..보기 좋으라고... tran_date  을 맨 처음 조회 하도록 변경했음;

BIN_TO_NUM() 함수에서 비트가 '1' 로 셋팅 되는 부분이..
레벨이 바뀌는 부분..이라고 생각하면 될듯..
이부분은 좀 ^^ 설명이 힘드네..ㅋㅋ

하지만 이해 하리라고 믿는다..'')?

-----------------------------------------------------------------------
여기서 문제...!!

각각의 하나의 컬럼에 대해서 모든 집계 가 필요하다면 어떻게 해야할까나???

company_cd , customer_cd  별 집계 ,
customer_cd , subject          별 집계
company_cd , subject          별 집계
company_cd , customer_cd ,  subject  각각의 집계등등... 모든 경우의 수..

-----------------------------------------------------------------------

 
by darkneo | 2006/12/26 17:46 | SQL | 트랙백 | 덧글(0)
트랙백 주소 : http://darkneo.egloos.com/tb/2898070
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >
rss

skin by 이글루스