[ Oracle - Connect_By ]

 

 

☞ 예제

         

1. SELECT   column_name, ...
    FROM      table
    START WITH    initial-condition 
    CONNECT BY  [PRIOR] [ NOCYCLE ] recurse-condition ; 

2. 실행순서
    1. START WITH에 의해서 ROOT로 이동한다.
    2. CONNECT BY에 의해 트리를 작성한다.
    3. PRIOR에 기술된 방향으로 트리를 탐색한다.
    4. CONNECT BY의 조건이 적용되어 필요할 때에 트리의 가지를 제외한다.
    5. WHERE 조건을 적용하여 필요 때에 작 행을 제외한다. 
    6. ORDER BY 가 있으면 순서대로 행을 정렬한다.

3. PRIOR : 탐색 방향을 의미한다. 그러므로 부모 노드식 앞에 PRIOR를 붙이면 ROOT방향으로 
                탐색을 한다.

 

☞  * 9i 이상: connect by
      - sys_connect_by_path : 상관관계 쿼리에서 현재 로우 까지의 PATH 정보를 쉽게 얻어 올 수 있습니다.

☞  * 10g 이상: connect by
      - connect_by_root : 상관관계 쿼리에서 LEVEL이 0인 최상위 로우의 정보를 얻어 올 수 있습니다.
      - connect_by_is_leaf : 상관관계 쿼리에서 로우의 최하위 레벨 여부를 반환 합니다.
      - connect_by_iscycle

☞  * 계층 쿼리시 계층별로 정렬하기 위해.. order siblings by 
 
    예) 
select     mnu_srno, mnu_cd, mnu_nm,mnu_lvl, higrk_mnu_cd, cntRow
        
from       tcm_mnuinf01 a , tcm_main b
        
start with b.mnu_lvl = 0  
        
connect by prior b.mnu_cd = b.higrk_mnu_cd
        
order  siblings  by  b.SORT_SEQ
  
    설명) order by 로 sort할 경우 모든 데이터를 가지고 정렬을 하지만
          order  siblings  by 각 계층별로 정렬을 한다.

'(DB) Oracle > SQL.통계-Connect by' 카테고리의 다른 글

Oracle - wm_concat  (0) 2017.01.21
Oracle - connect_by_isleaf  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - PIVOT  컬럼 목록 구하기 ]

 

-- 정의   : PIVOT()함수를 사용할때 컬럼갯수를 알아야만 한다.
--          결과 컬럼을 정의해 주지 않으면 PIVOT()함수를 사용할 수 없다.
--          
--          월갯수(from~to)를 알수 없을 경우에는 PIVOT()함수를 사용할 없게 된다.
--          
--          그런데, Dynamic SQL 문장을 사용하게 되면 SQL 문장을 작성할 때는 컬럼을 정의하지 않고
--          PIVOT()함수 정의 된 SQL 문장을 실행하기 전에  
--          월 갯수를 파악하여  PIVOT()함수에 추가한다.
--          (즉, myBatis 에서  FOR PLAN_YM IN ($COLUMN_LIST$)  와 같이 함)

 


SELECT
 (CASE WHEN GRP_ID   = '0' THEN PLAN_YM
             
WHEN MM_COUNT <  6  THEN '소계'
             
WHEN MM_COUNT =  6 AND FIRST_SECOND_TYPE = '0' THEN '상반기'
             
WHEN MM_COUNT =  6 AND FIRST_SECOND_TYPE = '1' THEN '하반기'
             
WHEN MM_COUNT = 12                             THEN '년계'
             
ELSE '총계' END) AS PLAN_YM
     , FIRST_SECOND_TYPE         
--0:상반기,  1:하반기
     , MM_COUNT                  
--1:Table 컬럼 sum()값.  2이상:소계, 합계 컬럼임
     , GRP_ID                    
--GROUPING_ID()함수 결과 값.
     , COL_ROWNUM                
--컬럼 ROWNUM
  
FROM
 (
        
SELECT YEAR_DATA
             , PLAN_YM
             , FIRST_SECOND_TYPE
             , 
COUNT(FIRST_SECOND_TYPE) AS MM_COUNT
             , 
GROUPING_ID(YEAR_DATA, FIRST_SECOND_TYPE, PLAN_YM) AS GRP_ID
          
FROM (
                --2013.10 ~ 201502 월까지 존재 하는 테이블일 경우
                
WITH YY_MM AS
                    ( 
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('201310', 'YYYYMM'), ROWNUM), 'YYYYMM') AS PLAN_YM
                        
FROM DUAL
                      CONNECT BY LEVEL <= 17 )
                
SELECT SUBSTR(B.PLAN_YM, 1,4)                   AS YEAR_DATA
                     , B.PLAN_YM                                
AS PLAN_YM
                     , 
FLOOR ((SUBSTR(B.PLAN_YM,5,2) - 1) / 6)  AS FIRST_SECOND_TYPE
                  
FROM YY_MM B
               )
        
GROUP BY ROLLUP(YEAR_DATA, FIRST_SECOND_TYPE, PLAN_YM)
       )
 
WHERE GRP_ID IN ('0', '1', '7') 
    
OR (MM_COUNT = 12 AND GRP_ID = 3) ;

 

 

Posted by 농부지기
,

[ Oracle - PIVOT Grid.Header 목록 구하기 ]

 

-- 정의   : 반복 컬럼이 1 ~ 3개 일 경우
--          PIVOT 함수 사용중  시작년월~종료년월 까지 자료를 조회 할 경우
-- 사용처 : PIVOT 조회결과를 화면에 보여 주려면  화면.Grid.Header를 dynamic하게 그려줘야 된다.
--          이때 고정컬럼을 항상 정해졌기 때문에 문제가 없고
--          반복컬럼과 중간에 소계, 합계가 들어 갈 경우 
--          아래 SQL문 결과를 통해서 Grid.Header를 그려줄 수 있다.

 


SELECT (CASE WHEN GRP_ID   = '0' THEN PLAN_YM
             
WHEN MM_COUNT <  6  THEN '소계'
             
WHEN MM_COUNT =  6 AND FIRST_SECOND_TYPE = '0' THEN '상반기'
             
WHEN MM_COUNT =  6 AND FIRST_SECOND_TYPE = '1' THEN '하반기'
             
WHEN MM_COUNT = 12                             THEN '년계'
             
ELSE '총계' END) AS PLAN_YM
       
--실 컬럼명은 변수로 받아야 됨
     , 
DECODE(COL_GUBN_GRP, 1, '비중', 2, '매출액', 3, '이익금') AS COL_NAME
     , FIRST_SECOND_TYPE         
--0:상반기,  1:하반기
     , MM_COUNT                  
--1:Table 컬럼 sum()값.  2이상:소계, 합계 컬럼임
     , GRP_ID                    
--GROUPING_ID()함수 결과 값.
     , COL_ROWNUM                
--컬럼 ROWNUM
     , COL_GUBN_GRP              
--반복컬럼이 1개 이상일 경우 순서
  
FROM (
        
WITH YY_MM AS
           (
            
SELECT YEAR_DATA
                 , PLAN_YM
                 , FIRST_SECOND_TYPE
                 , 
COUNT(FIRST_SECOND_TYPE) AS MM_COUNT
                 , 
GROUPING_ID(YEAR_DATA, FIRST_SECOND_TYPE, PLAN_YM) AS GRP_ID
              
FROM (SELECT SUBSTR(A.PLAN_YM, 1,4)                     AS  YEAR_DATA
                         , A.PLAN_YM                               
   AS PLAN_YM
                         , 
FLOOR ((SUBSTR(A.PLAN_YM,5,2) - 1) / 6)    AS  FIRST_SECOND_TYPE
                      
FROM ( --2013.10 ~ 201502 월까지 존재 하는 테이블
                             
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('201310', 'YYYYMM'), ROWNUM), 'YYYYMM') AS PLAN_YM
                               
FROM DUAL
                            
CONNECT BY LEVEL <= 17 
                           ) A
                   )
            
GROUP BY ROLLUP(YEAR_DATA, FIRST_SECOND_TYPE, PLAN_YM)
           )
        
SELECT PLAN_YM
             , FIRST_SECOND_TYPE
             , MM_COUNT
             , GRP_ID
             
--** 맨 앞쪽  1은  변수로 받아야 됨. (반복컬럼 갯수 임)
             , 
DECODE(3, 1, ROWNUM, 2, (ROWNUM * 2) - 1, (ROWNUM * 3) - 2) AS COL_ROWNUM   
             , 1      
AS COL_GUBN_GRP
          
FROM  YY_MM
         
WHERE  GRP_ID IN ('0', '1', '7') OR (MM_COUNT = 12 AND GRP_ID = 3)

        
UNION ALL

        
SELECT PLAN_YM
             , FIRST_SECOND_TYPE
             , MM_COUNT
             , GRP_ID
             
--** 맨 앞쪽  2는  변수로 받아야 됨. (반복컬럼 갯수 임)
             , 
DECODE(3, 2, (ROWNUM * 2) - 0, (ROWNUM * 3) - 1) AS COL_ROWNUM  
             , 2      
AS COL_GUBN_GRP
          
FROM  YY_MM
         
WHERE ( GRP_ID IN ('0', '1', '7') OR (MM_COUNT = 12 AND GRP_ID = 3) ) 
           
AND 2 <= 2    --** 오른쪽  2는  변수로 받아야 됨. (반복컬럼 갯수 임)

       
UNION ALL

        
SELECT PLAN_YM
             , FIRST_SECOND_TYPE
             , MM_COUNT
             , GRP_ID
             , (
ROWNUM * 3) - 0 AS COL_ROWNUM  
             , 3          
      AS COL_GUBN_GRP
          
FROM  YY_MM
         
WHERE ( GRP_ID IN ('0', '1', '7') OR (MM_COUNT = 12 AND GRP_ID = 3) ) 
           
AND 3 = 3    --** 오른쪽  3은  변수로 받아야 됨. (반복컬럼 갯수 임)
       )
 ORDER BY COL_ROWNUM ;
 

 

Posted by 농부지기
,