본문 바로가기

   
Programming/ORACLE

8일차!

반응형

무결성 제약조건    - 테이블에 유효하지않는 데이터가 입력되는것을 방지.

 

 

종류

  not null     - 열에 null 포함되지 않도록 지정.

 

  unique       - 테이블 전체에서 고유한 값을 가지도록 지정.

 

  primary key  - 테이블에서 행을 고유하게 식별하도록 지정. 행을 대표할수 있게 .

 

  foreign key  - 열에 값이 입력될때 참조 테이블(다른 테이블) 지정된 열을 참조.

               - 참조되는 칼럼은 반드시 프라임키나 유닉 제안조건이 지정된 컬럼이어야함.

 

  check        - 열에 입력가능한 값을 미리 지정함.

 

제약조건 정의

 

     컬럼 레벨에서 제약조건 정의하기.

       - 각각의 컬럼이 가져야 제약조건을 정의할 있다.

  CREATE TABLE 테이블명 (

     컬럼명 데이터타입 CONSTRAINT 제약조건이름 제약조건 타입

);

 

 

     테이블 레벨에서 제약조건 정의하기.

       - 하나 이상의 컬럼을 조합해서 제약조건을 정의할 있다.

  CREATE TABLE 테이블명 (

     컬럼명 테이터타입

     컬럼명 테이터타입

     ...

     CONSTRAINT 제약조건이름 제약조건타입 (컬럼명, ...),

)

     컬럼들을 미리 지정해놓고. 하나 이상일때니까 1개도 .

 

 

아래껀 두개이상의 제약조건을 만들때.

NOT NULL, PRIMARY 제약조건이면 위에거밖에 안됨.

 아래거는두개이상을 조합해서 하나의 제약조건으로 걸어버림.

위에껀 1개에 1.

 

 

제약조건을 걸때 학생 테이블이 있어, 거기 학번, 이름이있겠지.

근데, 100번도 101 102 3번학생 홍길동 김유신 강감찬 이순신이 있다하면,

 

과목 테이블이 있는거야 과목테이블엔

과목코드, 과목 번호 같은게 있겠지.

 S_001 002 003

 전자기학, 재료역학, 전자실험1 이런게 있다고 하자고, 이런 과목들이 있어

 

수강 테이블이 있는거지.

수강에는 어떤 학생이 어떤 과목을 듣냐는거

학번, 과목번호가 있는 테이블. 그러면, 여기엔 어떤 값이 가야하지?

이런게 들어가면 안되니까. 이런경우는 절대 안되는게

100번학생이 S001 수강했어 근데, 100번이 S001 수강하면 안되니까.

101학생이 S001 들어도 되지만, 학생이 두개를 중복해서 들으면 안되니까.

 

그런 경우에는 아래걸 쓴다는거지. 그런 방법일때 아래껄 쓴다는거지.

두개이상의 제약을 조합.

 

학번이랑 과목번호 둘다 고유 해야하니까. 두개가 합침(조합) 하려면 아래껄 쓴다.

 

 

 

나중에 프로젝트를 하면, 테이블 명세서를 받게되는데 테이블의 데이터 타입 컬럼의 간단한 설명

제약조건이 어떤게 걸렸는지 그게 엑셀로 되어있는 명세서를 받게됨.

 

 

NOT NULL 체크 제약조건임.

포린키, 유니크, 체크 제약조건은 많아도 되지만

프라이머리키 제약조건은 무조건 1.

제약조건 추가/삭제

 

     - 추가

          alter table 테이블명

          add contraint 제약조건명 제약조건타입 (컬럼명)

 

     - 삭제

          alter table 테이블명

          drop contraint 제약조건명;

 

 

제약조건 정의하기

 -- 회원 테이블 (회원번호, 이름, 연락처, 이멜, 생일, 가입일, 프로필사진, ...)

 

 -- 회원번호       -> 회원을 대표하는 컬럼

 -- 이름           -> 반드시 입력되야함

 -- 연락처         -> 중복되는 x

 -- 이메일         -> 중복되는 x, 반드시 입력되야함

 -- 포인트         -> 0보다 값이어야함.

 

  CREATE TABLE SAMPLE_MEMBER (

     no      number          constraint mem_no_pk      primary key,

     namk    varchar2(50)    constraint mem_name_nn    not null,

     gender  char(1)         constraint mem_gender_ck  check (gender in ('F', 'M') ),

     tel     varchar2(20)    constraint mem_tel_uk     unique,

     email   varchar2(100)   constraint mem_email_nn   not null,

     point   number          constraint mem_point_ck   check(point >0),

     regdate date            defalut    sysdate,

 

     constraint mem_email_uk unique (email)

);

 

 

-- 차일드 테이블에서 참조하고 있는 값을 삭제 할수 없다.

-- 차일드 테이블에서 참조하고 있는 테이블은 삭제 불가.

-- 차일드 테이블을 먼저 삭제후 부모 테이블을 삭제 가능.

 

 

 -- 회원들이 작성하는 게시판 테이블 (글번호, 제목, 작성자, 내용, 조회수, 작성일, ...)

  CREATE TABLE SAMPLE_BOARD (

 

)

 

 

-- 정의된 제약조건 정보가 있는 Dictionary -> USER_CONSTRAINTS

SELECT *

FROM USER_CONSTRAINTS

WHERE TABLE_NAME = 'EMPLOYEES';

 

-- 정의된 시퀀스 정보가 있는 딕셔너리.

SELECT *

FROM USER_SEQUENCES;

 

-- 정의된 테이블 정보가 있는 딕셔너리

SELECT *

FROM USER_TABLES;

 

-- 정의된 인덱스 정보가 있는 .

SELECT *

FROM USER_INDEXES;

 

-- 정의된 정보가 있는 .

SELECT *

FROM SYS.USER_VIEWS;

 

 

제약조건 추가/삭제

     - 추가

          alter table 테이블명

          add contraint 제약조건명 제약조건타입 (컬럼명)

 

     - 삭제

          alter table 테이블명

          drop contraint 제약조건명;

 

(View)

     - 뷰는 가상의 테이블임

     - 하나 or 두개 이상의 테이블을 사용, 가상의 테이블() 만들 있음.

 

쓰는 이유?

     - 데이터에 대한 접근을 제한하기 위해.

     - 복잡한 쿼리를 쉽게 작성하려고.

     - 동일한 데이터로 다양한 결과를 얻기 위해.

뷰의 생성

     Create or replace

          as SELECT구문

          with read only;

삭제

     Drop view 뷰이름

 

인라인

     - SQL문에서 사용되는 서브쿼리

     - SELECT문의 FROM절에 있는 서브쿼리를 인라인뷰 라고 부름.

     -

 

 

껐다 켜도, 뷰는 살아있음.

 

 

-- 부서번호가 80번인 사원의 정보를 가진

 

CREATE VIEW EMP_80

  as SELECT employee_id, last_name, salary

  FROM EMPLOYEES

  where DEPARTMENT_ID = 80;

 

SELECT *

FROM EMP_80

WHERE SALARY > 10000;

 

 

-- 서재수의 사은품?

SELECT A.GNO, A.GNAME, POINT, B.GNAME as gift_name

FROM GOGAK A, gift B

where A.POINT >= B.G_START and A.POINT <= B.G_END

and A.GNAME = '서재수';

 

-- 고객 정보, 포인트에 해당하는 사은품 정보 주는 .

CREATE or REPLACE VIEW gogak_gift -- 새로 만들거나, 바꾸거나

  as select a.gno, A.gname as name,

    point, b.gname as gift_name, SUBSTR(A.JUMIN, 1, 6) || '*******' as jumin

    FROM GOGAK A, GIFT B

    WHERE a.point >= B.G_START and a.point <= B.G_END

    with read only; -- 읽기전용.

  

    -- 서재수의 사은품?

SELECT GNO, NAME, POINT, GIFT_NAME

FROM GOGAK_GIFT

where NAME = '서재수';

 

 

SELECT DEPARTMENT_ID as id,  round(avg(SALARY)) as avg_sal

FROM EMPLOYEES

group by  DEPARTMENT_ID

ORDER BY AVG(SALARY) DESC;

 

 

SELECT DEPARTMENT_ID, DEPARTMENT_NAME

FROM DEPARTMENTS;

 

 

SELECT a.id, d.DEPARTMENT_NAME, a.avg_sal

FROM DEPARTMENTS D, (SELECT DEPARTMENT_ID as id,

                      round(avg(SALARY)) as avg_sal

                      FROM EMPLOYEES

                      group by  DEPARTMENT_ID)  a

WHERE a.id = D.DEPARTMENT_ID

ORDER BY a.avg_sal DESC;

 

-- 사번, 이름, 급여, 급여등급을 표시하는 SQL

 

--SELECT E.EMPLOYEE_ID, E.last_name, E.SALARY, G.Grade

--FROM EMPLOYEES E, (SELECT GRADE_LEVEL as Grade

--                   FROM JOB_GRADES) as G

 

SELECT E.EMPLOYEE_ID, E.LAST_NAME, E.SALARY, G.GRADE_LEVEL as Grade

FROM EMPLOYEES E, JOB_GRADES G

where E.SALARY >= G.LOWEST_SAL

and E.SALARY <= G.HIGHEST_SAL;

 

-- 사원 테이블의 모든 사원들의 사원번호, 이름,

-- 부서번호, 부서이름, 급여 급여등급 정보를 포함한 만들기.

 

create or REPLACE VIEW EMP_SALARY_DETAIL as

SELECT E.DEPARTMENT_ID, e.last_name,

       D.DEPARTMENT_NAME, E.SALARY, G.GRADE_LEVEL

FROM EMPLOYEES E, JOB_GRADES G, DEPARTMENTS D

where E.SALARY >= G.LOWEST_SAL

and E.SALARY <= G.HIGHEST_SAL

and E.DEPARTMENT_ID = D.DEPARTMENT_ID

WITH READ ONLY;

 

SELECT *

FROM EMP_SALARY_DETAIL

where last_name = 'King';

 

-- 인라인뷰에서 순위 계산.

-- 급여를 가장 많이 받는 사원3.

SELECT ranking, last_name, salary

FROM (SELECT ROW_NUMBER() OVER (ORDER BY salary desc) as ranking,

             last_name,

             salary

        FROM EMPLOYEES)

where ranking <=3;

 

 

-- 1997 이후, Clerk.

SELECT EMPLOYEE_ID, LAST_NAME, HIRE_DATE, JOB_Id

FROM EMPLOYEES

WHERE JOB_ID = 'ST_CLERK'

and HIRE_DATE > '1997-01-01'

ORDER BY HIRE_DATE;

 

--...????

 

--2 커미션 사람 표시.

 

SELECT LAST_NAME, JOB_ID, SALARY, COMMISSION_PCT

FROM EMPLOYEES

WHERE COMMISSION_PCT is not null

ORDER BY SALARY DESC;

 

-- 3.

SELECT LAST_NAME, SALARY as before, salary*1.1 as after

FROM EMPLOYEES

WHERE COMMISSION_PCT is null

ORDER BY SALARY;

 

-- 4 일한 .

SELECT LAST_NAME, round(months_between (SYSDATE, hire_date)) as month,

      round(months_between (SYSDATE, hire_date)/12) as years

FROM EMPLOYEES;

 

-- 5 J K L M 시작 이름 사원

SELECT LAST_NAME

FROM EMPLOYEES

WHERE substr(LAST_NAME, 1, 1) in ('J', 'K', 'L', 'M');

 

-- 6

SELECT LAST_NAME, SALARY, COMMISSION_PCT as com,

  CASE

    WHEN commission_pct is null then 'no'

    when commission_pct is not null THEN 'yes'

   end as yes_or_no

FROM employees;

-- 2005 이후

SELECT *

FROM EMPLOYEES

WHERE HIRE_DATE > TO_DATE('2006/01/01', 'yyyy-mm-dd')

and JOB_ID like '%CLERK';

 

-- 2.

SELECT LAST_NAME, JOB_ID, TO_CHAR(SALARY, '$999,999') as sal,

                                                    to_char(COMMISSION_PCT) as comm

FROM EMPLOYEES

WHERE COMMISSION_PCT is not null

ORDER BY SALARY DESC;

 

-- 3.

SELECT LAST_NAME || ' 급여가 10% 인상되어 ' || SALARY *1.1 ||

                                              ' 달러가 되었심심'as salsal

FROM EMPLOYEES

WHERE COMMISSION_PCT is null;

 

-- 4.

SELECT LAST_NAME, trunc(months_between (SYSDATE, hire_date)) as month,

       trunc(months_between (SYSDATE, hire_date)/12) as years

FROM EMPLOYEES

ORDER BY HIRE_DATE;

 

-- 4 정확.

SELECT LAST_NAME, trunc(months_between (SYSDATE, hire_date)/12) as years,

                  trunc(mod(months_between (SYSDATE, hire_date), 12)) as dal

FROM EMPLOYEES;

 

 

with MONTHS_TABLE as (

SELECT LAST_NAME, MONTHS_BETWEEN(SYSDATE, hire_date) months

FROM EMPLOYEES

)

SELECT last_name, trunc(months/12) nyeon, trunc(mod(months, 12)) dal

FROM MONTHS_TABLE; -- 임시의 테이블.

 

 

-- 5.

SELECT LAST_NAME

FROM EMPLOYEES

WHERE substr(LAST_NAME, 1, 1) in ('J', 'K', 'L', 'M');

 

-- 6

SELECT LAST_NAME, SALARY,

  CASE

    WHEN commission_pct is null then 'no'

    when commission_pct is not null THEN 'yes'

   end as yes_or_no

FROM employees;

 

 

SELECT LAST_NAME, SALARY,

  CASE

    WHEN commission_pct is not null then 'yes'

    ELSE 'no'

  end comm

from EMPLOYEES;

 

SELECT LAST_NAME, SALARY,

       decode(commission_pct, null, 'no', 'yes') comm

FROM EMPLOYEES;

 

SELECT LAST_NAME, SALARY,

       nvl2 (to_char(commission_pct), 'yes', 'no') comm

FROM EMPLOYEES;

 

-- 7 1800위치 부서정보 찾고, 부서아디와, 사원테이블 조인.

SELECT D.DEPARTMENT_ID, D.LOCATION_ID, E.LAST_NAME, E.JOB_ID, E.SALARY

FROM DEPARTMENTS D, EMPLOYEES E

WHERE D.LOCATION_ID = 1800

and D.DEPARTMENT_ID = E.DEPARTMENT_ID;

 

-- 8. 이름이 n으로 끝나는 . ?

SELECT COUNT(*)

FROM EMPLOYEES

WHERE LAST_NAME like '%n';

 

SELECT COUNT(*)

FROM EMPLOYEES

where substr(LAST_NAME, length(last_name), 1) = 'n';

 

-- 9

SELECT DEPARTMENT_ID, COUNT(*)

FROM EMPLOYEES E

GROUP BY DEPARTMENT_ID;

 

SELECT D.DEPARTMENT_ID, D.DEPARTMENT_NAME, D.LOCATION_ID, nvl(e.cnt, 0)

FROM (SELECT DEPARTMENT_ID, COUNT(*) as cnt

      FROM EMPLOYEES

      GROUP BY DEPARTMENT_ID ) E, DEPARTMENTS D

WHERE e.DEPARTMENT_ID(+) = D.DEPARTMENT_ID;

 

-- 10, 부서번 10,20, 50 업무 표시.

SELECT DISTINCT JOB_ID

FROM EMPLOYEES

WHERE DEPARTMENT_ID in (10, 20, 50);

 

-- 11

SELECT E.JOB_ID, COUNT(*) as cnt

FROM DEPARTMENTS D, EMPLOYEES E

WHERe D.DEPARTMENT_ID = E.DEPARTMENT_ID

AND D.DEPARTMENT_NAME in ('Administration', 'Executive')

GROUP BY E.JOB_ID

ORDER BY cnt desc;

 

-- 12, 입사일이 16 이전의 사원명 입사일 표시.

SELECT LAST_NAME, to_char(HIRE_DATE, 'yyyy-mm-dd') as ippsa

FROM EMPLOYEES

WHERE to_char(HIRE_DATE, 'dd') < '16';

 

-- 13.

 

-- 14.

SELECT sa.LAST_NAME as sawon, ma.LAST_NAME as "s'manager",

                            ma.SALARY, G.GRADE_LEVEL

FROM EMPLOYEES sa, EMPLOYEES ma, JOB_GRADES G

WHERE sa.MANAGER_ID = ma.EMPLOYEE_ID

and ma.SALARY > 15000

 

AND ma.SALARY >= G.LOWEST_SAL

and ma.SALARY <= G.HIGHEST_SAL;

 

-- 16. 평높은 부서의 최저급여

 

SELECT DEPARTMENT_ID, min(SALARY)

FROM EMPLOYEES

GROUP BY DEPARTMENT_ID

HAVING avg(SALARY) = (SELECT max(avg(SALARY))

                      FROM EMPLOYEES

                      GROUP BY DEPARTMENT_ID);

 

-- 17 SA_REP 없는 부서번, 이름, 위치.

SELECT *

FROM EMPLOYEES E, DEPARTMENTS D

WHERE JOB_ID <> 'SA_REP';

 

 

 

-- 18 모든 사원번호, 이름, 급여, 부서번, 부서별 평균 급여

 

-- 3 미만.

SELECT D.DEPARTMENT_ID as Dn, D.DEPARTMENT_NAME as DNAME, COUNT(*)

FROM DEPARTMENTS D, EMPLOYEES E

WHERE D.DEPARTMENT_ID = E.DEPARTMENT_ID

GROUP by D.DEPARTMENT_ID, D.DEPARTMENT_NAME

HAVING count(*) < 3;

 

SELECT B.DEPARTMENT_ID, B.DEPARTMENT_NAME

FROM (SELECT d.DEPARTMENT_ID, COUNT(*) cnt

      FROM DEPARTMENTS D, EMPLOYEES E

      WHERE D.DEPARTMENT_ID = E.DEPARTMENT_ID

      GROUP by D.DEPARTMENT_ID

      HAVING count(*) <3) A, DEPARTMENTS B

wHERE a.DEPARTMENT_ID = B.DEPARTMENT_ID;

 

-- 사원 가장많은.

 

 

-- 사원 가장 적은 부서

SELECT a.DEPARTMENT_ID, B.DEPARTMENT_NAME, cnt

FROM (SELECT DEPARTMENT_ID, COUNT(*) cnt

      FROM EMPLOYEES

      GROUP BY DEPARTMENT_ID

      having COUNT(*) = (SELECT min(count(*))

                         FROM EMPLOYEES

                         GROUP BY DEPARTMENT_ID)) A, DEPARTMENTS B

WHERE A.DEPARTMENT_ID = B.DEPARTMENT_ID;

 

--19 패스

 

 

 

 

--20

SELECT LAST_NAME, TO_CHAR(HIRE_DATE, 'DAY')

FROM EMPLOYEES;

--WHERE to_char(HIRE_DATE, 'DAY') in (SELECT to_char(HIRE_DATE, 'DAY') day;

                                  

                                   

                                  

                                  

SELECT *

FROM EMPLOYEES

WHERE to_char(HIRE_DATE, 'DAY')

              in (SELECT to_char(HIRE_DATE, 'DAY'), count(*)

                    FROM employees

                    GROUP BY to_char(HIRE_DATE, 'DAY')

                    HAVING COUNT(*) = (SELECT max(COUNT(*))

                                       FROM EMPLOYEES

                                       GROUP BY to_char(HIRE_DATE, 'DAY')));

 

 

 

 

 

 

인텍스는 사람 이름이 100 있을때, 1 또는 2 있을때.

 

그러니까, 1~3%정도 찾을때? 그게 유리함.

 

책에서 찾았을때, 무언갈.

ELS if 436페이지에 가면 있겠지. 그걸 찾았겠지.

페이지 전체에서 10 넘길때마다 데이터가 나오거나, 데이터가 몰려있을때, 갔다 왔다 언제할래.

인덱스라 하는건 where 조건절에 나오고, 그게 유리하고

 

굉장히 적은 데이터. 전체의 1~3% 나오면, 그게 유리한데 그게 아니면 유리하지않음. 풀스캔 하는게 좋음.

 

결합 인덱스- 컴포짓

 

프랜차이즈 사장이라 했을때,

 

경기도 지역에 A B C D 지역에.

서울의 지역에 E F G H 지역에.

 

지역을 먼저 찾고, 지점을 찾는.

 

select --

from --

where area = '서울'

and store = '역삼'

 

먼저 서울 찍어버리면 서울만 서울에서만. 거기서 역삼 위치데이터를 가져오고.

역삼적고 서울 찾아버리면, 서울 경기 다른 지역 찾아보는 불필요하게 되서.

 

결합의 순서가 대단히 중요함.

 

서울 치고 들어오고 역삼을 찾으면, 찾기 쉬우니까.

 

순서에 맞게 where절에 조건을 적어야, 성능향상을 볼수있음.

 

100개에서 1~5 찾는거랑 1000개에서 1~5 찾는거랑은 다르니까.

 

첫째로 인덱스는 언제 생성되는가.

     1. 묵시적 <- 우리가 테이블을 만들때 primary key, unique 제약조건을 정의하면

               해당 컬럼의 값을 가진 인덱스가 만들어 진다. 이미 만들어져 있는. 그런.

[생성]

     2. 명시적 <- 처럼 만들(정의)었을때. 명시적 중에는.. 전부터 인덱스란건, 쿼리에 조회성능을 향상시키기 위해서, .

               관리는 오라클이 알아서함, 인덱스가 만들어지면, 변동(추가, 삭제, 수정 등등) 있을때, 지들이 알아서 .

               우린 신경쓸일이 아님. 애초. 사실 삭제 수정등등은 몰라도 추가는 중요하지않음. 계속계속

               순서상으로 뒤로만 쌓이는거니까 중간이 바뀌는게 아니니까.

               그냥 뒤로만 넣으면 되니까. 오라클이 어려워하지않아함.

               인덱스는 무조건 정리된 값을 가지고있음.

               날짜를 가지고 계속 잡아둠. 같은 그런건 자동이라 상관없는데

               기존의 데이터를 앞으로 뒤로 그런건 인덱스 걸면 속도가 많이 느려지고, 전체를 만들어야하니까.

               오라클이 싫어함. 그런 성격은 인덱스 다루지 말것.

                    보통 우리가 다루는건 날짜에 관련이니 신경 안써도 무방할지도.

 

               편의점같은걸 생각해보면 하루하루 카드 긁고, 돈막 받고 그러는데 계속 쉼없이

               인서트가 될건데. 지역, 지점, 날짜 그렇게 인덱스를 걸어두면 좋을것같다.

              

               은행만 봐도

               적게 보여줘야 인덱스가 그렇다했듯

               작은 날짜. 일주일이나 하루 이틀정도만 보여주는게 그런 이유.

 

 

정리해서 인덱스

     쿼리의 실행속도 향상을 위해

     인덱스는 데이터와 데이터의 위치정보를 갖고있음.

     테이블 삭제하면 인덱스도 삭제됨.

 

인덱스의 생성

     Create index 인덱스명

     on 테이블명 (컬럼명 정렬방법, 컬럼명 정렬방법, ....);

 

인덱스의 종류

   하나만 있어도 되지만, 여러개 있어도 .

 

     - non unique index

      중복된 값을 허용.

      (사원명, 책제목, 학생명, ...)

      create index 인덱스명 on 테이블명(컬럼명 정렬방식, ...)

 

     - unique index

      중복된 값을 허용x

      (민번, 이멜, 전번, ...)

      create unique index 인덱스명 on 테이블명(컬럼명 정렬방법, ... )

 

     - compisite index

      두개 이상의 (컬럼) 사용해서 인덱스 정의.

 

 








Rollup과 Cube

     ㄴ 롤업과 큐브는 group by절의 기능을 향상시킴.
     ㄴ 롤업과 큐브는 group by절의 실행결과에 소계 및 합계 정보를 추가함.
     ㄴ 롤업은 단계별 소계 정보추가
     ㄴ 큐브는 모든경우의 수에대한 소계(합계) 정보를 추가.

Grouping
     ㄴ 그룹by에 의해서 산출된 행인지, 롤업이나 큐브에 의해서 산출된 행인지를 표시.
     ㄴ 그룹바이에 의해서 산출된 행은 0,
       롤업이나 큐브에 의해서 산출된 행은 1을 반환
     ㄴ 주로 롤업이나 큐브에 의해서 조회된 결과에서 NULL값을 대체할
       목적으로 사용됨.





정교수부교수시간교수롤업 합
10132510
10212710
1032439
큐브합6815
















SELECT DEPTNO, COUNT(*)

FROM PROFESSOR

GROUP BY DEPTNO

ORDER BY DEPTNO asc;

 

 

SELECT '합계', COUNT(*)

FROM PROFESSOR;

 

 

SELECT DEPTNO, COUNT(*)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO)

ORDER BY DEPTNO asc;

 

 

-- 그룹by 때문에 나온게 0, 그루핑.

SELECT decode(GROUPING(DEPTNO), 0, to_char(DEPTNO), 'tot'), COUNT(*)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO)

ORDER BY DEPTNO asc;

 

 

SELECT DEPTNO, POSITION, count(*)

FROM PROFESSOR

GROUP BY DEPTNO, POSITION

ORDER BY DEPTNO, POSITION;

 

 

SELECT DEPTNO, POSITION, COUNT(*)

FROM PROFESSOR

GROUP BY ROLLUP (DEPTNO, POSITION)

order BY DEPTNO, POSITION;

 

 

SELECT DEPTNO, POSITION, COUNT(*), GROUPING(DEPTNO), GROUPING(POSITION)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO, POSITION);

 

 

SELECT DEPTNO, POSITION, COUNT(*), GROUPING(DEPTNO), GROUPING(POSITION)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO, POSITION);

 

-- 소계만 표시.

SELECT DEPTNO, POSITION, count(*), GROUPING(DEPTNO), GROUPING(POSITION)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO, POSITION)

HAVING GROUPING(DEPTNO) = 1 and GROUPING(POSITION) = 1;

 

-- 총계만 표시

SELECT COUNT(*)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO, POSITION)

HAVING GROUPING(DEPTNO) = 1 and GROUPING(POSITION) = 1;

 

-- 총계는 제외하고.

SELECT DEPTNO, POSITION, count(*), GROUPING(DEPTNO), GROUPING(POSITION)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO, POSITION)

HAVING GROUPING(DEPTNO) = 0;

 

-- 총계를 제외한 소계 표시.

SELECT DEPTNO, DECOde(GROUPING(position), 1, '소계', position) , count(*)

FROM PROFESSOR

GROUP BY ROLLUP(DEPTNO, POSITION)

HAVING GROUPING(DEPTNO) = 0;

 

 

SELECT DEPTNO, POSITION, COUNT(*)

FROM PROFESSOR

GROUP BY DEPTNO, POSITION

ORDER BY DEPTNO, POSITION;

 

SELECT DEPTNO, POSITION, COUNT(*)

FROM PROFESSOR

WHERE DEPTNO in (101, 102, 103)

GROUP BY rollup (DEPTNO, POSITION);

 

SELECT DEPTNO, POSITION, COUNT(*)

FROM PROFESSOR

GROUP BY cube (DEPTNO, POSITION);

 

SELECT to_char(DEPTNO), POSITION, COUNT(*)

FROM PROFESSOR

WHERE DEPTNO in (101, 102, 103)

GROUP BY DEPTNO, POSITION

UNION

SELECT to_char(DEPTNO), '소계', COUNT(*)

FROm PROFESSOR

WHERE DEPTNO in (101, 102, 103)

GROUP BY DEPTNO     -- ROLLUP(DEPTNO, POSITION)

 

union

SELECT POSITION, '직위별 소계', COUNT(*)

FROm PROFESSOR

WHERE DEPTNO in (101, 102, 103)

GROUP BY POSITION;  -- cube(DEPTNO, POSITION) 큐브 안씀.


반응형