1. 임시로 사용할 테이블 생성하기



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 테이블 생성
 
CREATE TABLE MY_DUAL AS(
    SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
    SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
    SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
    SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL
    SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
    SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL
    SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
    SELECT 8 ID, 2600 SALARY FROM DUAL
);
 
-- 기존 테이블 컬럼만 복사해 새 테이블 생성
 
CREATE TABLE COPY_NEW_TABLE AS(
    SELECT * FROM EXIST_TABLE_NAME
    WHERE 1=2 -- FALSE
);
cs



2. 컬럼 ADD, MODIFY, RENAME, DROP 사용하기 - 1


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-- 1. 컬럼 ADD 
-- ALTER TABLE 테이블명 ADD 새 컬럼명 이름  데이터타입;
 
ALTER TABLE MY_DUAL ADD ANNUAL_INCOME VARCHAR2(1000);
UPDATE MY_DUAL SET ANNUAL_INCOME = SALARY;
 
-- 2. 컬럼 MODIFY 
-- ALTER TABLE 테이블 명 MODIFY 컬럼명 데이터타입;
 
ALTER TABLE MY_DUAL MODIFY SALARY VARCHAR2(1000);
 
-- 3. 컬럼 RENAME
-- ALTER TABLE 테이블명 RENAME COLUMN 기존컬럼명 TO 바꿀컬럼명;
 
ALTER TABLE MY_DUAL RENAME COLUMN ANNUAL_INCOME TO SALARY;
 
-- 4. 컬럼 DROP
-- ALTER TABLE 테이블명 DROP COLUMN 삭제할 컬럼명;
 
ALTER TABLE MY_DUAL DROP COLUMN SALARY;
cs



3. 컬럼에 데이터가 있을때 데이터 유형 바꾸는 방법 - 2



1
2
3
4
5
6
7
8
9
10
11
12
13
-- 컬럼에 데이터가 있을때 데이터 유형 바꾸는 방법
 
-- 1. 새 이름으로 새 컬럼을 하나 생성 (ADD)
ALTER TABLE MY_DUAL ADD ANNUAL_INCOME VARCHAR2(1000);
 
-- 2. 새 컬럼에 기존 데이터를 다시 입력 (SET)
UPDATE MY_DUAL SET ANNUAL_INCOME = SALARY;
 
-- 3. 기존 컬럼 삭제 (DROP)
ALTER TABLE MY_DUAL DROP COLUMN SALARY;
 
-- 4. 새 컬럼의 이름을 기존 컬럼 이름으로 바꿈 (RENAME)
ALTER TABLE MY_DUAL RENAME COLUMN ANNUAL_INCOME TO SALARY;
cs



현재 SALARY 컬럼의 데이터 유형은 NUMBER 

SALARY 컬럼은 데이터를 갖고 있다.

데이터를 가지고있는 컬럼에 대한 데이터유형 변경은 허용하지 않는다.


그러므로 새 이름의 필요한 데이터유형의 새로운 컬럼을 하나 생성한 뒤 

기존 컬럼이 가지고 있는 데이터를 새로운 데이터유형의 컬럼에 넣어주고(이동)

기존 컬럼을 삭제(DROP) 하고 새 이름의 새컬럼 이름을 기존 컬럼의 이름으로 바꿔주면 된다.






ORACLE 컬럼 중복값 제거(필터) 방법 정리



1. RANK() OVER, DENSE_RANK() OVER, ROW_NUMBER() OVER 함수




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- ORACLE 데이터의 중복 값을 제거(필터)하는 방법
-- RANK() OVER, DENSE_RANK() OVER, ROW_NUMBER() OVER 함수
 
SELECT ID
         , SALARY
         , RANK() OVER (ORDER BY SALARY DESC) RANK_FUNC -- 같은 값 공통 순위 1등이 3명 있다면 다음 순위는 2등이 아닌 4등이 된다.
         , DENSE_RANK() OVER (ORDER BY SALARY DESC) DENSE_RANK_FUNC -- 같은 값 공통 순위 1등이 3명 있다면 다음 순위는 2등이 된다.
         , ROW_NUMBER() OVER (ORDER BY SALARY DESC) ROW_NUMBER_FUNC -- 같은 값 공통 순위 1등이 3명 있다해도 순위가 각각 1,2,3등 매겨진다.
  FROM
         (
            SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
            SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
            SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
            SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
            SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
            SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
          );
cs


결과



2. ROW_NUMBER() OVER 사용한 SALARY 중복값 제거 - 1




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- ROW_NUMBER() OVER 사용한 SALARY 중복값 제거 - 1
 
SELECT A1.*
  FROM (
            SELECT ID
                     , SALARY
                     , ROW_NUMBER() OVER (PARTITION BY SALARY ORDER BY ID)  AS RN
              FROM
                     (
                        SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
                        SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
                        SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
                        SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
                        SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
                        SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
                        SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
                        SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
                      )
           ) A1
WHERE A1.RN = 1
;
cs



결과




3. GROUP BY를 사용한 SALARY 중복값 제거 - 2



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- GROUP BY를 사용한 SALARY 중복값 제거 - 2
 
SELECT MIN(ID)
         , SALARY
  FROM
         (
            SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
            SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
            SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
            SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
            SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
            SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
          )
GROUP BY SALARY
ORDER BY SALARY
;
cs



결과




4. DISTINCT 를 사용한 SALARY 중복값 제거 - 3




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- DISTINCT 를 사용한 SALARY 중복값 제거 - 3
 
SELECT DISTINCT A1.SALARY
  FROM
         (
            SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
            SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
            SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
            SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
            SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
            SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
          ) A1
;
cs



결과




5. ROWID 를 사용한 SALARY 중복값 제거 - 4



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- ROWID를 이용한 SALARY 중복값 제거 - 4
 
-- 테이블 만들기 4-1
 
CREATE TABLE MY_DUAL AS(
    SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
    SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
    SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
    SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
    SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
    SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
    SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
    SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
)
;
 
-- 테이블에서 ROWID 이용 중복값 제거 4-2
 
SELECT ID, SALARY
  FROM MY_DUAL
WHERE ROWID IN (SELECT MIN(ROWID)
                              FROM MY_DUAL
                            GROUP BY SALARY)
;
cs



결과




ORACLE의 여러 함수를 사용해 컬럼의 중복되는 값 을 제거 할 수 있는 것을 확인했다.





ORACLE WITH AS 사용방법 - 1 



1
2
3
4
5
6
7
8
9
10
11
-- [WITH 구문 사용방법]
 
WITH AA AS
 (SELECT ROWNUM, 'TEST1', SYSDATE
    FROM DUAL
  UNION ALL
  SELECT ROWNUM, 'TEST2', SYSDATE
    FROM DUAL
  UNION ALL
  SELECT ROWNUM, 'TEST3', SYSDATE FROM DUAL)
SELECT * FROM AA;
cs

출력 결과

 ROWNUM 'TEST1' SYSDATE

 1

 TEST1

 2017-07-25 오후 6:14:08

 1

 TEST2

 2017-07-25 오후 6:14:08

 1

 TEST3

 2017-07-25 오후 6:14:08




ORACLE WITH AS 사용방법 - 2 




1
2
3
4
5
6
7
8
9
10
11
12
13
 -- [WITH 구문(2개 SUB쿼리) 사용방법]
 
 WITH AA AS (SELECT ROWNUM AS SEQ
                             , 'TEST1' AS NAME
                             , SYSDATE 
                      FROM DUAL),
          BB AS (SELECT ROWNUM AS SEQ
                              , 'TEST2' AS NAME
                              , SYSDATE
                       FROM DUAL)  
         SELECT * 
           FROM AA, BB 
          WHERE AA.SEQ = BB.SEQ 
cs


출력 결과


 SEQ

 NAME

 SYSDATE

 SEQ_1

 NAME_1

 SYSDATE_1

 1

 TEST1

 2017-07-25 오후 6:16:53

 1

 TEST2

 2017-07-25 오후 6:16:53





ORACLE 데이터 컬럼 여러개로 나누기, 데이터 컬럼 줄내림(줄바꿈), 정규표현식 사용하기




1. ORACLE 정규표현식 사용해 하나의 한줄의 데이터컬럼을 여러개의 컬럼으로 나누기



1
2
3
4
5
6
7
8
9
10
-- 정규표현식 사용해 하나의 한줄의 데이터컬럼을 여러개의 컬럼으로 나누기
SELECT * 
  FROM (
        SELECT REGEXP_SUBSTR(HELLO,'[^~!]+',1,LEVEL)  AS MY_REGEXP
          FROM (
                    SELECT '안녕하세요~!반갑습니다.' AS HELLO FROM DUAL   
                   ) A
         CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(HELLO,'[^~!]+'))+1
           ) A
    WHERE A.MY_REGEXP IS NOT NULL
cs


출력 결과


 안녕하세요

 반갑습니다.




2. ORACLE REPLACE 함수, 개행문자 CHR(10) 사용해 한 컬럼의 데이터 값을 줄내리기(줄바꿈)




1
2
3
4
5
-- REPLACE 함수, 개행문자 CHR(10) 사용해 한 컬럼의 데이터 값을 줄내리기
SELECT REPLACE(A.HELLO,'~!',CHR(10))  AS MY_REGEXP
  FROM (
            SELECT '안녕하세요~!반갑습니다.' AS HELLO FROM DUAL   
        ) A
cs


출력 결과


안녕하세요

반갑습니다.



3. ORACLE REPLACE 함수 사용, <br> 태그 넣어 jsp에서 받아올때 한줄씩 내려서 받기



1
2
3
4
5
-- REPLACE 함수 사용, <br> 태그 넣어 jsp에서 받아올때 한줄씩 내려서 받기
SELECT REPLACE(A.HELLO,'~!','<br>')  AS MY_REGEXP
  FROM (
            SELECT '안녕하세요~!반갑습니다.' AS HELLO FROM DUAL   
        ) A
cs


출력 결과 


 안녕하세요<br>반갑습니다.




DECODE문은 두가지 유형으로 사용된다.


'조건', 'IF', TRUE, FALSE


'조건', 'IF1', TRUE, 'IF2', TRUE ,'IF3' TRUE



1
2
3
4
5
6
7
SELECT DECODE('조건2''조건1''결과1'
                                , '조건2', DECODE('조건2-1','조건2-2','결과2-1','결과2-2')
                                , '조건3''결과3')
   FROM DUAL
   
   -- 다음 DECODE문을 보면 IF1 TRUE1, IF2 TRUE2, IF3 TRUE3이 적용된것이고
   -- 조건2로 DECODE문을 보면 IF TRUE FALSE로 조건이 맞지 않아 FALSE로 접근한 것을 알 수 있다.
cs


실행결과


결과 2-2 가 나오는것을 확인할 수 있다.


DECODE문은 NVL과 NVL2의 문법형식을 합쳐놓은 것이라 생각하면 이해하기 쉽다.



1
2
3
SELECT NVL('컬럼값이NULL일때','TRUE')
         , NVL2('컬럼값이NULL일때','TRUE','FALSE')
  FROM DUAL
cs


CASE문과 비슷하지만 DECODE문은 더 복잡한 분기처리와 쿼리양을 줄일수 있다고 생각한다.  





무결성 제약조건 종류


NOT NULL : 해당 컬럼 값으로 NULL을 허용하지 않는다.

UNIQUE : 테이블 내에서 해당 컬럼 값은 항상 유일한 값을 갖는다.

PRIMARY KEY : NULL을 허용하지 않고 중복된 값을 허용하지 않는다. NOT NULL 조건과 UNIQUE 조건을 결합한 형태

FOREIGN KEY : 참조되는 테이블의 컬럼 값이 존재하면 허용한다.

CHECK : 저장 가능한 값의 범위나 조건을 지정하여 설정한 값만 허용한다.


1. NOT NULL



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- NOT NULL 제약조건
CREATE TABLE MY_EMP
       (
       EMPNO NUMBER(4NOT NULL
     , ENAME VARCHAR2(10)
     , JOB VARCHAR2(9)
     , DEPTNO NUMBER(2)
       );
       
-- 테이블 조회
SELECT * FROM MY_EMP;
 
-- INSERT 허용
INSERT INTO MY_EMP(EMPNO, ENAME, JOB, DEPTNO) VALUES (1NULL,'SALESMAN'10); 
-- INSERT 시 EMPNO NOT NULL 제약조건으로 허용불가
INSERT INTO MY_EMP(EMPNO, ENAME, JOB, DEPTNO) VALUES (NULLNULL,'SALESMAN'20); 
cs


2. UNIQUE 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- UNIQUE 제약조건
CREATE TABLE MY_EMP2
       (
       EMPNO NUMBER(4UNIQUE
     , ENAME VARCHAR2(10)
     , JOB VARCHAR2(9)
     , DEPTNO NUMBER(2)
       );
 
-- 테이블 조회
SELECT * FROM MY_EMP2;
 
-- INSERT 허용
INSERT INTO MY_EMP2(EMPNO, ENAME, JOB, DEPTNO) VALUES (1NULL,'SALESMAN'10); 
-- INSERT 시 EMPNO UNIQUE 제약조건으로 허용불가
INSERT INTO MY_EMP2(EMPNO, ENAME, JOB, DEPTNO) VALUES (1NULL,'SALESMAN'20); 
cs



3. PRIMARY KEY



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- PRIMARY KEY 제약조건
CREATE TABLE MY_EMP4
             (
             EMPNO NUMBER(4CONSTRAINT MY_EMP4_EMPNO_PK PRIMARY KEY
           , ENAMR VARCHAR2(10CONSTRAINT MY_EMP4_ENAME_NN NOT NULL
           , JOB VARCHAR(9)
           , DEPTNO NUMBER(2)
             ); 
             
-- 테이블 조회
SELECT * FROM MY_EMP4;
 
-- INSERT 허용
INSERT INTO MY_EMP4 VALUES(7499'ALLEN''SALESMAN'30);
-- INSERT 시 PRIMARY KEY 제약조건으로 허용불가
INSERT INTO MY_EMP4 VALUES (7499'JONES''MANAGER'20); 
cs



4. FOREIGN KEY



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- FOREIGN KEY 제약조건
CREATE TABLE MY_EMP5
             (
             EMPNO NUMBER(4CONSTRAINT MY_EMP5_EMPNO_PK PRIMARY KEY
           , ENAME VARCHAR2(10CONSTRAINT MY_EMP5_ENAME_NN NOT NULL
           , JOB VARCHAR(9)
           , DEPTNO NUMBER(2CONSTRAINT MY_EMP5_DEPTNO_FK REFERENCES DEPT(DEPTNO)
             ); 
                    
-- 테이블 조회
SELECT * FROM MY_EMP5;
                
-- INSERT 허용 
INSERT INTO MY_EMP5 VALUES(7499'ALLEN''SALESMAN'30);
-- INSERT 시 FOREIGN KEY 제약조건으로 허용불가
INSERT INTO MY_EMP5 VALUES(7566'JOENS''MANAGER'50); 
cs



1. CREATE TABLE, ALTER TABLE, DROP TABLE, RENAME



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-- 테이블 생성
CREATE TABLE MY_TABLE(
       NAME VARCHAR2(10)
     , AGE NUMBER(10)
);
 
-- 생성된 테이블 조회
SELECT * FROM MY_TABLE;
 
-- 테이블에 컬럼 추가
ALTER TABLE MY_TABLE ADD ADDRESS VARCHAR2(10);
 
-- 테이블 컬럼명 수정
ALTER TABLE MY_TABLE RENAME COLUMN ADDRESS TO MY_ADDRESS;
 
-- 테이블 컬럼 삭제
ALTER TABLE MY_TABLE DROP(MY_ADDRESS);
 
-- 테이블 데이터 삽입
INSERT INTO MY_TABLE(NAME,AGE) VALUES('이상현',28);
cs



2. DELETE, TRUNCATE, DROP



1
2
3
4
5
6
7
8
-- DELETE는 이전에 할당되었던 영역은 삭제되어 빈 TABLE이나 CLUSTER에 그대로 남아 있게 된다.
DELETE FROM MY_TABLE;
 
-- TRUNCATE 는 TABLE이나 CLUSTER에서 모든 행을 삭제하는 빠르고 효율적인 방법
TRUNCATE TABLE MY_TABLE;
 
-- TABLE이나 CLUSTERED TABLE에 부여된 권한도 삭제된다.
DROP TABLE MY_TABLE;
cs


3. 데이터 딕셔너리, 데이터 딕셔너리 뷰


데이터 딕셔너리는 스키마,사용자,객체,권한,룰,데이터베이스 정보 등 정보관리하는 별도의 객체를 의미한다.


데이터 딕셔너리는 시스템 정보를 가지고 있기 때문에 보통 데이터딕셔너리 뷰를 통해 조회한다.


데이터 딕셔너리 뷰는 3종류로 나눌수 있다.


ALL : 모든 접근 가능

DBA : DB관리자만 접근 가능

USER : 사용자만 접근 가능


1. ALL 접근



1
2
3
4
5
6
7
8
9
10
11
12
-- ALL 접근
SELECT *
  FROM ALL_OBJECTS
;  
 
SELECT OWNER
     , OBJECT_NAME
     , OBJECT_TYPE
  FROM ALL_OBJECTS
 WHERE OBJECT_TYPE='TABLE'
   AND OWNER = 'SCOTT'
;
cs


출력 결과



2. USER 접근



1
2
3
4
5
6
7
8
9
-- USER 접근
SELECT *
  FROM USER_OBJECTS
;
 
SELECT OBJECT_NAME
     , OBJECT_TYPE
  FROM USER_OBJECTS
 WHERE OBJECT_TYPE='TABLE'
cs


출력 결과




클러스터란 ?


  디스크로부터 데이터를 읽어오는 시간을 줄이기 위해서 조인이나 자주 사용되는 테이블의 데이터를 디스크의 같은 위치에 저장시키는 방법이다.


 

클러스터된 테이블과 클러스터 되지 않은 테이블의 차이


  테이블이 처음 생성될 때 행은 일반적으로 세그먼트의 첫 익스텐트의 첫 블록부터 삽입된다.


  정규 테이블로 저장될 경우 EMP와 DEPT은 서로 다른 세그먼트에 위치하게 됩니다. 이 말은 테이블이 자신들 고유의 블록을 사용한다는 뜻이다.


  즉, EMP 테이블의 행을 저장하는데 사용된 블록은 DEPT 테이블의 데이터를 저장하지 않습니다. 그 반대의 경우도 마찬가지이다.


  테이블 EMP와 DEPT의 클러스터로 저장되면 동일 클러스터 세그먼트를 공유하게 된다. 


  이 세그먼트의 블록은 양 테이블의 행을 모두 저장할 수 있다.


  테이블이 클러스터로 저장되면 클러스터는 물리적 저장 단위가 되고 테이블은 논리적 엔티티 즉, 클러스터의 일부분이 된다.


 

클러스터의 장점


  - 그룹된 컬럼 데이터 행들이 같은 데이터 Block에 저장되기 때문에 디스크 I/O를 줄여 준다.


  - 클러스터된 테이블 사이에 조인이 발생할 경우 그 처리 시간이 단축 된다.


  - 클러스터키 열을 공유하여 한번만 저장하므로 저장 영역의 사용을 줄인다.



테이블 클러스터링의 특징


  클러스터는 데이터 조회 성능을 향상 시키지만 데이터 저장, 수정, 삭제 또는 한 테이블 전체 Scan의 성능을 감소 시킨다.


클러스터 하기 좋은 테이블


- 주로 조회가 자주 발생하고 수정이 거의 발생하지 않는 테이블

- 컬럼안의 많은 중복 데이터를 가지는 테이블

- 자주 Join되는 테이블


클러스터 Key가 되기 좋은 컬럼


- 데이터 값의 범위가 큰 컬럼

- 테이블 간의 조인에 사용되는 컬럼


클러스터 key가 되기 나쁜 컬럼


- 특정 데이터 값이 적은 컬럼

- 자주 데이터 수정이 발생하는 컬럼

- LONG, LONG RAW 컬럼은 포함할 수 없다.

+ Recent posts