'(DB) Oracle/SQL.통계-단계별Study'에 해당되는 글 7건

  1. 2017.01.21 Oracle - MODEL 1단계
  2. 2017.01.21 Oracle - OVER 1단계
  3. 2017.01.21 Oracle - GROUPING() 3 단계
  4. 2017.01.21 Oracle - ROUPING() 2 단계
  5. 2017.01.21 Oracle - GROUPING() 1 단계
  6. 2017.01.21 Oracel - CUBE 1 단계
  7. 2017.01.21 Oracle - ROLLUP 1 단계

[ Oracle - MODEL 1단계 ]

 

정의 : MODEL 절은 SELECT 구문과 같이 사용되어 결과셋의 각각의 항목들을 연관배열 처럼취급해서 
       이러한 항목들을 일정한 계산규칙에 따라 계산을 수행한뒤 새로운 결과셋을 리턴한다.
       장점은 테이블을 이차원배열로 접근할  있어서 엑셀의 함수처럼 계산을 할수 있다
       즉
, 앞뒤 로우의 특정행에 접근할  있다

☞  [구문형식]

 

  SELECT ...
  FROM   ...
  MODEL [main]
        [ reference models ]
        [ PARTITION BY (<컬럼>) ]
        DIMENSION BY (<컬럼>)    
                         <------------ 로우를 식별할 기준이 되는 컬럼을 명시
        MEASURES (<컬럼>)                    
                         <
------------ 새로 계산이 되는 컬럼 명시
               [ IGNORE NAV ] | [ KEEP NAV ]
        [ RULES
          
<------------ RULES 절에는 MEASURES 절에서 명시한 컬럼들만 기술   있다.
                   [ UPSERT | UPDATE ]
                   [ AUTOMATIC ORDER | SEQUENTIAL ORDER ]
                   [ ITERATE (n) [UNTIL <CONDITION> ]
            ]
                   (<CELL_ASSIGNMENT > = <expression> ...) ;

☞ 예제

 

WITH MODEL_T AS
(
 SELECT '201101' TERM, 100000 SALARY FROM DUAL UNION ALL
  SELECT '201102' TERM, 112000 SALARY FROM DUAL UNION ALL
  SELECT '201103' TERM, 123000 SALARY FROM DUAL UNION ALL
  SELECT '201104' TERM, 131000 SALARY FROM DUAL UNION ALL
  SELECT '201105' TERM, 122000 SALARY FROM DUAL UNION ALL
  SELECT '201106' TERM, 140000 SALARY FROM DUAL UNION ALL
  SELECT '201107' TERM, 160000 SALARY FROM DUAL
) 
SELECT TERM, ORI_SAL, TAXES 
  FROM MODEL_T
MODEL
    DIMENSION BY (TERM) 
    MEASURES (SALARY ORI_SAL, SALARY TAXES )
RULES(
    ORI_SAL['200701'] = ORI_SAL['200701'] * 0.33,      -- 순서를  바꿔봤다.^^
    TAXES  ['200702'] = TAXES  ['200702'] * 0.33,
    TAXES  ['200703'] = TAXES  ['200703'] * 0.33,
    TAXES  ['200704'] = TAXES  ['200704'] * 0.33,
    TAXES  ['200705'] = TAXES  ['200705'] * 0.33,
    TAXES  ['200706'] = TAXES  ['200706'] * 0.33  )
ORDER
 BY 1

☞  

 

 DIMENSION 컬럼이 TERM 이다. 
   , DIMENSION 컬럼의 값을 연관배열의 KEY 처럼 사용해서 로우를 식별한다.
   여기서는 '20070x' 라는 컬럼값으로 로우를 식별하고 있다. 

SELECT TERM
     , SAL 
  FROM model_t
MODEL
    DIMENSION BY (term )
    MEASURES (SALARY sal)
RULES(
   SAL['QTR1']   = SAL['200701']+SAL['200702']+SAL['200703'],
   SAL['TOTAL1'] = sum(sal)[term IN ('200701','200702') ]
   SAL['TOTAL2'] = sum(sal)[term IN ('200701','200702') ]
)
ORDER
 BY 1;

 sum() 함수도 사용할  있는데 배열키값에 저런식으로도 사용이 가능.
 MODEL 절을 사용할 경우 SELECT 문장의 컬럼명은 MEASURES 절에서 반드시 명시한
    것들만 올수 있다. 
    따라서 그룹쿼리를 사용하기전에 MODEL절을 사용하여 계산을 마친 결과셋을 인라인뷰로
    사용해야한다. 
    왜냐면 SELECT 구문의 컬럼명이 MODEL 절에 종속적이기 때문이다.

 WITH TOTAL_T AS (
    SELECT NO, CAMP_CODE, GUBUN
         , MONTH_1, MONTH_2,MONTH_3, MONTH_4, MONTH_5, MONTH_6, MONTH_7,MONTH_8
         , MONTH_9, MONTH_10,MONTH_11,MONTH_12 
         , TOTAL 
      FROM DATA_1_T
    MODEL 
        DIMENSION BY (ID )
        MEASURES (TOTAL,MONTH_1, MONTH_2,MONTH_3, MONTH_4, MONTH_5,MONTH_6, MONTH_7
                 ,MONTH_8, MONTH_9,MONTH_10, MONTH_11,MONTH_12
                 ,ID NO,GUBUN,CAMP_CODE)
    RULES(
      TOTAL[ ANY ] = MONTH_1[cv(ID)] + MONTH_2[CV(ID)] + MONTH_3[CV(ID)] +MONTH_4[CV(ID)] + MONTH_5[CV(ID)] + MONTH_6[CV(ID)] + MONTH_7[CV(ID)] +MONTH_8[CV(ID)] + MONTH_9[CV(ID)] + MONTH_10[CV(ID)] + MONTH_11[CV(ID)] +MONTH_12[CV(ID)]
         )
)
 SELECT ROW_NUMBER() OVER (ORDER BY 1) RN1
      , ROW_NUMBER() OVER( PARTITION BY DTL_RGN_CODE ORDER BY GUBUN ) RN2
      , DECODE( ROW_NUMBER() OVER(PARTITION BY DTL_RGN_CODE ORDER BY GUBUN ) 
              , 1, DTL_RGN_CODE,' ') " "
      , NVL2(GUBUN,GUBUN,'합계') GUBUN
      , sum(MONTH_1) jan
      , sum(MONTH_2) feb
      , sum(MONTH_3) mar
      , sum(MONTH_4) apr
      , sum(MONTH_5) may
      , sum(MONTH_6) jun
      , sum(MONTH_7) jul
      , sum(total)   total
   from total_t a, CAMP_INFO_T b
  where a.CAMP_CODE = b.CAMP_CODE
  group by rollup(DTL_RGN_CODE,gubun) ;

 

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - OVER 1단계  (0) 2017.01.21
Oracle - GROUPING() 3 단계  (0) 2017.01.21
Oracle - ROUPING() 2 단계  (0) 2017.01.21
Oracle - GROUPING() 1 단계  (0) 2017.01.21
Oracel - CUBE 1 단계  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - OVER 1단계 ]

 

정의 : OVER analytic_clause 
        해당
 함수가 쿼리 결과 집합에 대해 적용되라는 지시어로써 FROM, WHERE, GROUP BY 
        HAVING
 이후에 계산되어 진다.

☞  

 

PARTITION BY 
   하나
 이상의 컬럼 또는 적합한 표현식이 사용될  있고 하나 이상의 컬럼 또는 
   표현식에
 의한 그룹으로 쿼리의 결과를 파티션한다. 
   
 구가 생략되면 단일 그룹처럼 쿼리 결과 집합이 처리된다. 
ORDER BY 

   하나
 이상의 컬럼 또는 적합한 표현식이 사용될  있고 
   하나
 이상의 컬럼 또는 표현식을 기준으로 파티션 내의 데이터를 정렬한다. 
   표현식은
 컬럼의 별칭 또는 위치를 나타내는 숫자를 사용할  없다. 

 1. 문제

 

  자료 : 기준일자 영업유무
         19810101 Y
         19810103 N
         19810104 Y
         19810105 N
         19810106 N
         19810107 N
         19810108 N
         19810109 N
         19810111 Y
     경우

결과 : 기준일자로 정렬해서 위에서 부터 Y 갯수를 COUNT 하기
             기준일자 영업유무  Y갯수
             19810101 Y         1
             19810103 N         1
             19810104 Y         2
             19810105 N         2
             19810106 N         2
             19810107 N         2
             19810108 N         2
             19810109 N         2
             19810111 Y         3;

WITH T AS ( 
     SELECT '19810101' DAT, 'Y' YN FROM DUAL UNION ALL
     SELECT '19810103' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810104' DAT, 'Y' YN FROM DUAL UNION ALL
     SELECT '19810105' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810106' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810107' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810108' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810109' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810111' DAT, 'Y' YN FROM DUAL 
) 
  SELECT DAT, YN, COUNT( DECODE( YN, 'Y', 1 ) ) OVER( ORDER BY DAT ASC ) GRP 
    FROM T  ;   

☞  문제2

 

     자료 : 기준일자 영업유무
            19810101 Y
            19810103 N
            19810104 Y
            19810105 N
            19810106 N
            19810107 N
            19810108 N
            19810109 N
            19810111 Y
    
 경우

    결과 : 기준일자로 정렬해서 위에서 휴무일자를 제외한 영업일자를 찾아오기
             기준일자 영업유무  영업일자
             19810101 Y         19810101
             19810103 N         19810104
             19810104 Y         19810104  
             
19810105 N         19810111 
             19810106 N         19810111    
             
19810107 N         19810111 
             19810108 N         19810111 
             19810109 N         19810111 
             19810111 Y         19810111;

WITH T AS ( 
     SELECT '19810101' DAT, 'Y' YN FROM DUAL UNION ALL
     SELECT '19810103' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810104' DAT, 'Y' YN FROM DUAL UNION ALL
     SELECT '19810105' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810106' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810107' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810108' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810109' DAT, 'N' YN FROM DUAL UNION ALL
     SELECT '19810111' DAT, 'Y' YN FROM DUAL UNION ALL
     SELECT '19810112' DAT, 'N' YN FROM DUAL
) 
SELECT DAT, YN, GRP, MAX( DAT ) OVER( PARTITION BY GRP ) A_DAT 
FROM ( 
       SELECT DAT, YN, COUNT( DECODE( YN, 'Y', 1 ) ) OVER( ORDER BY DAT DESC ) GRP 
         FROM T 
) 
ORDER BY DAT ;

 

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - MODEL 1단계  (0) 2017.01.21
Oracle - GROUPING() 3 단계  (0) 2017.01.21
Oracle - ROUPING() 2 단계  (0) 2017.01.21
Oracle - GROUPING() 1 단계  (0) 2017.01.21
Oracel - CUBE 1 단계  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - GROUPING() 3 단계 ]

 

 

목표 : GROUPING, GROUPING_ID, GROUP_ID  대해서 알아 보기

☞  

 

1. GROUPING(name)
  - name 컬럼으로 GROUP BY 의해서 SUM 결과는 0, CUBE, ROLLUP 의해 합산된 결과는 1
2
. GROUPING_ID(name1, name2)
  - GROUPING(name1) || GROUPING(name2) 결과를 2진수로 판단해서  값을 10진수로 환산한 
  - ) 00 => 0
        01 => 1
        10 => 2
        11 => 3
3
. GROUP_ID()
   - ROLLUP이나 CUBE 의한 결과에서 중복된 자료가 존재시 구별가능하다.
   - 필요이유는 중복자료가 여러번 나올  있기 때문에 필터링하는데 유용하다.
   - 만약 n 특정 그룹핑에서 중복이 존재한다면, GROUP_ID 0~n-1 범위의 수를 반환한다.

 

WITH salary AS
(
    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '05' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '06' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '07' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '08' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '04' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '05' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '06' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '07' SMONTH, 112000 SALARY FROM dual
)
SELECT
 DEPT, NAME, COUNT(SMONTH) CNT, SUM(SALARY) SALARY
     , GROUPING(DEPT) G_DEPT, GROUPING(NAME) G_NAME
     , GROUPING(DEPT) + GROUPING(NAME) G_SUM
     , GROUPING_ID(DEPT, NAME) GING_ID
     , GROUP_ID()              G_ID
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY CUBE(DEPT, NAME)   --GROUP BY ROLLUP(DEPT, NAME) 
 ORDER BY GROUPING(DEPT), DEPT, GROUPING(NAME), NAME ;

   DEPT    NAME     CNT    SALARY     G_DEPT  G_NAME  G_SUM  GING_ID  G_ID
 
-------------------------------------------------------------------------
   인사부   구하라    4    870000       0         0      0       0      0
   인사부   이주리    3    480000       0         0      0       0      0
   인사부   저미주    4    448000       0         0      0       0      0
   인사부            11   1798000       0         1      1       1      0
   총무부   강모리    3   1570000       0         0      0       0      0
   총무부   구하라    4    840000       0         0      0       0      0
   총무부   저미주    3    327000       0         0      0       0      0
   총무부            10   2737000       0         1      1       1      0
            강모리    3   1570000       1         0      1       2      0
            구하라    8   1710000       1         0      1       2      0
            이주리    3    480000       1         0      1       2      0
            저미주    7    775000       1         0      1       2      0
                     21   4535000       1         1      2       3      0

 

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - MODEL 1단계  (0) 2017.01.21
Oracle - OVER 1단계  (0) 2017.01.21
Oracle - ROUPING() 2 단계  (0) 2017.01.21
Oracle - GROUPING() 1 단계  (0) 2017.01.21
Oracel - CUBE 1 단계  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - ROUPING() 2 단계 ]

 

☞  

 

1. partition by 함께 사용하여 부서를 한번만 인쇄하기
   소계
, 합계  명칭 보여주기

WITH salary AS
(

    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '05' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '06' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '07' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '08' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '04' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '05' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '06' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '07' SMONTH, 112000 SALARY FROM dual
)

SELECT DECODE(ROW_NUMBER() OVER(PARTITION BY DEPT ORDER BY NAME), 1, DEPT, '')DEPT
     , DECODE(GROUPING(NAME), 1, (DECODE(GROUPING(DEPT), 1, '총계', '소계')), NAME)NAME
     , COUNT(*), SUM(SALARY), GROUPING(DEPT), GROUPING(NAME)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT, NAME) 
-- GROUP BY CUBE(DEPT, NAME) 
 HAVING GROUPING(DEPT) + GROUPING(NAME) > 0 ;

 

 DEPT      NAME     COUNT(*)      SUM(SALARY)      GROUPING(DEPT)   GROUPING(NAME)
 
----------------------------------------------------------------------------------
 인사부    구하라       4          870000            0                 0
           이주리       3          480000            0                 0
           저미주       4          448000            0                 0
           소계         11        1798000            0                 1   <--
 총무부    강모리       3         1570000             0                 0
           구하라       4          840000             0                 0
           저미주       3          327000             0                 0
           소계        10         2737000             0                 1   <--
           강모리       3         1570000             1                 0   <--
           구하라       8         1710000             1                 0   <--
           이주리       3          480000             1                 0   <--
           저미주       7          775000             1                 0   <--
           총계        21         4535000             1                 1   <--

 

 2. 부서별소계, 합계만 보여주기

 

  DEPT      COUNT(*)      SUM(SALARY)      GROUPING(DEPT)   GROUPING(NAME)
 
----------------------------------------------------------------------------------
 인사부        11         1798000            0                 1
 총무부        10        2737000             0                   1
 총계          21         4535000             1                   1

2.1 첫번째 방법

WITH salary AS ( .. )
SELECT
 DECODE(GROUPING(NAME), 1, (DECODE(GROUPING(DEPT), 1, '총계', DEPT)), DEPT)DEPT
     , COUNT(*), SUM(SALARY), GROUPING(DEPT), GROUPING(NAME)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT, NAME) 
 HAVING GROUPING(DEPT) + GROUPING(NAME) > 0 ;

--2.2 두번째 방법

WITH salary AS ( .. )
 SELECT DEPT
      , COUNT(*), SUM(SALARY), GROUPING(DEPT)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT) ;

☞  3. 부서별소계, 사원별합계, 총계만 보여주기

 

  TITLE      NAME     COUNT(*)      SUM(SALARY)      GROUPING(DEPT)   GROUPING(NAME)
 
----------------------------------------------------------------------------------
 부서별총계    인사부        11         1798000             0                 1
               총무부        10         2737000             0                 1
 사원별총계    강모리         3         1570000             1                 0
               구하라         8         1710000             1                 0
               이주리         3          480000             1                 0
               저미주         7          775000             1                 0
 총계                        21         4535000             1                 1

* 차후 공부를 해서 아래 SQL문은 좀더 TUNING  필요할 

WITH salary AS ( .. )
SELECT
 CASE WHEN DEPT = '총계' THEN '총계'
            WHEN ROW_NUMBER() OVER(ORDER BY DEPT) = 1 THEN '부서별총계'
            WHEN ROW_NUMBER() OVER(ORDER BY NAME) = 1 THEN '사원별총계'
       END TITLE
     , DECODE(DEPT_ID, 0, DEPT, (DECODE(NAME_ID, 1, '', NAME))) NAME
     , CNT, SALARY, DEPT_ID, NAME_ID
  FROM (
        SELECT DECODE(GROUPING(DEPT) + GROUPING(NAME), 2, '총계', DEPT) DEPT, NAME
             , COUNT(*) CNT, SUM(SALARY) SALARY, GROUPING(DEPT) DEPT_ID,GROUPING(NAME) NAME_ID
          FROM salary
         WHERE SMONTH BETWEEN '01' AND '12'
         GROUP BY CUBE(DEPT, NAME) 
        HAVING GROUPING(DEPT) + GROUPING(NAME) > 0 
       ) A
 ORDER  BY DEPT_ID, NAME, NAME_ID ;

 

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - OVER 1단계  (0) 2017.01.21
Oracle - GROUPING() 3 단계  (0) 2017.01.21
Oracle - GROUPING() 1 단계  (0) 2017.01.21
Oracel - CUBE 1 단계  (0) 2017.01.21
Oracle - ROLLUP 1 단계  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - GROUPING() 1 단계 ]

 


☞  정의

 

GROUPING()함수 정의
1. GROUPING() 함수
 ROLLUP() CUBE() 함수에 모두 사용할  있다.
2. GROUPING
함수는
  SQL  결과가  GROUP BY 의해서 나온 결과는 0 반환하고
   ROLLUP이나
 CUBE 의해서 산출된 결과에는 1 반환한다.
3. 
결론은
, GROUPING함수는 SQL 문에 의해서 나온결과가  GROUP BY 자료인지,
   ROLLUP, CUBE
 의해서 나온결과인지를   있도록 지원해주는 함수 이다.

 

--SQL1

WITH salary AS
(
    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '05' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '06' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '07' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '08' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '04' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '05' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '06' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '07' SMONTH, 112000 SALARY FROM dual
)

SELECT DEPT, NAME, COUNT(*), SUM(SALARY), GROUPING(DEPT), GROUPING(NAME)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY CUBE(DEPT, NAME)
 ORDER BY DEPT, NAME;

 DEPT      NAME     COUNT(*)      SUM(SALARY)      GROUPING(DEPT)   GROUPING(NAME)
 
----------------------------------------------------------------------------------
 인사부    구하라       4          870000            0                 0
 인사부    이주리       3          480000            0                 0
 인사부    저미주       4          448000            0                 0
 인사부                11         1798000            0                 1   <--CUBE의한 결과
 총무부    강모리     3         1570000             0                 0
 총무부    구하라     4          840000             0                 0
 총무부    저미주     3          327000             0                 0
 총무부             10        2737000             0                   1   <--CUBE의한 결과
        강모리     3         1570000             1                 0   <--CUBE 의한결과
        구하라     8         1710000             1                 0   <--CUBE 의한결과
        이주리     3          480000             1                 0   <--CUBE 의한결과
        저미주     7          775000             1                 0   <--CUBE 의한결과
                 21         4535000             1                   1   <--CUBE의한 결과

* 위 결과중  아래자료는 (부서, 이름에 대한 총계 이므로 1,1 결과가 나왔음)
SQL2 : 
기타
 추가 SQL문들
       WITH
 위자료를 활용

SELECT DEPT, NAME, COUNT(*), SUM(SALARY), GROUPING(DEPT), GROUPING(NAME)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY DEPT, CUBE(NAME)   --GROUP BY CUBE(DEPT), NAME
 ORDER BY DEPT, NAME;

 

 

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - OVER 1단계  (0) 2017.01.21
Oracle - GROUPING() 3 단계  (0) 2017.01.21
Oracle - ROUPING() 2 단계  (0) 2017.01.21
Oracel - CUBE 1 단계  (0) 2017.01.21
Oracle - ROLLUP 1 단계  (0) 2017.01.21
Posted by 농부지기
,

[ Oracel - CUBE  1 단계 ]

 

☞  정의

 

1. DATA 아래와 같을 경우,  
   
부서별총계
, 직원별총계,  부서별,직원별 총계  구하기
   [아래
 자료를 보면  직원은 여러부서로 이동가능 하므로.. 
        아래와 같은 자료가 존재   있다]
   * 만약
,  ROLLUP으로 하게 된다면, ROLLUP 2 사용후 UNION  해야 한다.
     아래와
 같은 결과가 나오기 위해서 SQL 문을 구현 (3가지의 SQL 문으로  봤음)

☞ 결과

 

DEPT     NAME     COUNT(*)      SUM(SALARY)
 
---------------------------------------------
 인사부   구하라       4             870000
 인사부   이주리       3             480000
 인사부   저미주       4             448000
 인사부               11            1798000
 총무부   강모리       3            1570000
 총무부   구하라       4             840000
 총무부   저미주       3             327000
 총무부                10            2737000
                       21            4535000  <--위에서 여기까는 첫번재 ROLLUP이용한 결과
          강모리       3            1570000
          구하라       8            1710000
          이주리       3             480000
          저미주       7             775000
                       21            4535000  <-- 여기까지는  두번재 ROLLUP 이용한결과

**  결과를 보면 총계가 2개나왔다.  CUBE 사용하게 되면 자연스럽게 1개만 나오게 된다

☞  SQL1

 

WITH salary AS

(

    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '05' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '06' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '07' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '08' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '04' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '05' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '06' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '07' SMONTH, 112000 SALARY FROM dual
)

SELECT DEPT, NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT, NAME)

UNION ALL

SELECT '', NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(NAME) ;

☞   SQL2
 

-- UNION  했을 때의 결과 (data  with절로 처리)

SELECT DEPT, NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT, NAME)

UNION   

SELECT '', NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(NAME) ;


☞  SQL3

 

 

-- 아래쪽 SQL 문을 GROUP BY 로만  했을 때의 결과 (data  with절로 처리)

SELECT DEPT, NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT, NAME)

UNION ALL

SELECT '', NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY NAME ;

 

WITH salary AS
(
    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '05' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '06' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '07' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '구하라' NAME, '08' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '04' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '05' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '06' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '저미주' NAME, '07' SMONTH, 112000 SALARY FROM dual
)

SELECT DEPT, NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY CUBE(DEPT, NAME)
 ORDER BY DEPT, NAME ;

 

 

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - OVER 1단계  (0) 2017.01.21
Oracle - GROUPING() 3 단계  (0) 2017.01.21
Oracle - ROUPING() 2 단계  (0) 2017.01.21
Oracle - GROUPING() 1 단계  (0) 2017.01.21
Oracle - ROLLUP 1 단계  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - ROLLUP  1 단계 ]

 

1. 정의 
   ROLLUP을 사용하면 그룹을 계층구조로 생성하고 그 계층구조 안에서 통계(그룹함수 적용)를 산출한다.
   만약, 그룹의 계층구조를 벗어나서 각 그룹이 독립적으로 존재할 경우의 통계도 필요하다면 
   CUBE를 사용한다.

☞  1. 직원별로 급여집계

 

WITH salary AS
(
    SELECT '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual
)
SELECT NAME, SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY NAME;

NAME
       SUM(SALARY)
-------- ------------
구하라      870000
저미주      327000

☞ 2. 직원별로 급여집계와 총계 구하기

 

WITH salary AS
(
    SELECT '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual
)
SELECT NAME, SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(NAME);


 NAME     SUM(SALARY)
-------- ------------
구하라       870000
저미주       327000
             327000    <-- ROLLUP 사용한 결과 NAME항목 전체 대한 총계가  왔음

☞  3. 부서별, 직원별 급여집계, 급여개월수  총계 구하기

 

WITH salary AS
(
    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual
)
SELECT DEPT, NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY DEPT, NAME;


DEPT       NAME        COUNT(*)     SUM(SALARY)
------------------------------------------
인사부    구하라       4            870000
인사부    이주리       3            480000
총무부    강모리       3           1570000
총무부    저미주       3            327000

☞   
 

4.  DATA 가지고 아래와 같은 결과를 얻는 SQL

DEPT       NAME        COUNT(*)     SUM(SALARY)
------------------------------------------
인사부    구하라         4            870000  <--
인사부    이주리         3            480000
인사부                   7           1350000  <--
총무부    강모리         3           1570000
총무부    저미주         3            327000
총무부                   6           1897000
                        13            3247000  <--

 ROLLUP(DEPT, NAME) 결과    DEPT, NAME 대한 합계 조회
 ROLLUP(DEPT, NAME) 결과    DEPT  대한 합계 조회
 ROLLUP(DEPT, NAME) 결과    전체계월수, 전체급여합계액 조회

WITH salary AS
(
    SELECT '총무부' DEPT, '저미주' NAME, '01' SMONTH, 100000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '02' SMONTH, 115000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '저미주' NAME, '03' SMONTH, 112000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '07' SMONTH, 510000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '08' SMONTH, 450000 SALARY FROM dual UNION ALL
    SELECT '총무부' DEPT, '강모리' NAME, '09' SMONTH, 610000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '01' SMONTH, 200000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '02' SMONTH, 210000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '03' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '구하라' NAME, '04' SMONTH, 230000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '01' SMONTH, 150000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '02' SMONTH, 160000 SALARY FROM dual UNION ALL
    SELECT '인사부' DEPT, '이주리' NAME, '03' SMONTH, 170000 SALARY FROM dual
)

SELECT DEPT, NAME, COUNT(*), SUM(SALARY)
  FROM salary
 WHERE SMONTH BETWEEN '01' AND '12'
 GROUP BY ROLLUP(DEPT, NAME);


☞  정리

 

-. 정의 : 1.그룹핑된 결과에 그룹별합계정보를 추가하여 조회한다.
          2. ROLLUP함수는 주로 GROUP BY와 같이 사용되며 주어진 Grouping조건에 따라 각 그룹의 
             그룹핑 항목이 있으면 우측부터 하나씩 제외하면서 그 결과를 반환한다.
-. ROLLUP(DEPT, NAME)을 하게 되면
   1. 먼저      , GROUP BY DEPT, NAME 과 같은 결과 가 나오고
   2. 그 다음에 , ROLLUP(DEPT, NAME)에 의해서   DEPT 에 대한 합계 조회
   3. 마지막으로, ROLLUP(DEPT, NAME)에 의해서   총계가 조회 됨  

'(DB) Oracle > SQL.통계-단계별Study' 카테고리의 다른 글

Oracle - OVER 1단계  (0) 2017.01.21
Oracle - GROUPING() 3 단계  (0) 2017.01.21
Oracle - ROUPING() 2 단계  (0) 2017.01.21
Oracle - GROUPING() 1 단계  (0) 2017.01.21
Oracel - CUBE 1 단계  (0) 2017.01.21
Posted by 농부지기
,