[DBMS_Oracle] CASE..WHEN...THEN


CASE..WHEN...THEN(조회된 값에 대한 조건 걸기)


조회해 올 때의 조건은 WHERE 문으로 조건을 걸어 가져올 수 있습니다.

하지만 가져온 값에 어떤 조건을 걸어 보여 주거나 또는 값을 변환할 필요가 있을 경우는 CASE...WHEN...THEN 문을 씁니다.

CASE WHEN 문에는 두 가지 형태의 사용 방법이 있습니다.


SELECT * FROM table명 WHERE

column명<검색할 컬럼명> CASE WHEN 'A'='B'<비교조건> THEN '2013' <처리조건>

ELSE 'C'<default 조건>

END<반드시 끝에 EMD를 써야한다>



1. 특정 Column으로 여러가지 값을 비교

SELECT CASE TO_CHAR(SYSDATE, 'YYYY') WHEN '2013' THEN SYSDATE 

   WHEN '2014' THEN SYSDATE + 1

              ELSE NULL END SYS_DATE

FROM DUAL;

 

CASE 와 WHEN 사이에 비교하고자 하는 Column 을 넣고

WHEN 과 THEN 사이에 비교하고자 하는 값을 넣어서 비교하는 방법입니다.


2. 여러가지 조건을 비교

SELECT CASE WHEN TO_CHAR(SYSDATE, 'YYYY') = '2013' THEN SYSDATE

                     WHEN TO_CHAR(SYSDATE, 'MM') = '11' THEN SYSDATE + 1 

             ELSE NULL END SYS_DATE 

FROM DUAL;

CASE 와 WHEN 사이는 비우고(컬럼없음), WHEN 과 THEN 사이에 내가 필요한 조건문을 WHERE 절에 넣는 것처럼 넣으면 됩니다.

2번의 경우에는 하나의 조건 뿐만 아니라 여러 개의 조건을 한꺼번에 넣을 수 있는 장점이 있습니다.


SELECT CASE WHEN TO_CHAR(SYSDATE, 'YYYY') = '2013' 

   AND TO_CHAR(SYSDATE, 'MM') = '10' THEN SYSDATE

                     WHEN TO_CHAR(SYSDATE, 'YYYY') = '2014' 

                     OR TO_CHAR(SYSDATE, 'MM') = '11' THEN SYSDATE + 1

            ELSE NULL END SYS_DATE 

FROM DUAL;

이상 조회된 값에 조건 걸어 사용하기였습니다.


3. 중첩된 CASE문
- 여러개의 CASE문을 중첩해서 사용할 수 있다.
SELECT  T1.STORE_ID
        ,T1.STORE_ADDR
        ,CASE WHEN T1.STORE_SIZE >= 100 THEN
                CASE WHEN T2.REGION_GD IN ('S') THEN 'High grade'
                     WHEN T2.REGION_GD IN ('A','B') THEN 'Mid Grade'
                     ELSE 'Low Grade'
                END
              WHEN T1.STORE_SIZE >= 50 THEN
                CASE WHEN T2.REGION_GD IN ('S', 'A') THEN 'High Grade'
                     WHEN T2.REGION_GD IN ('B') THEN 'Mid Grade'
                     ELSE 'Low Grade'
                END
             ELSE
                CASE WHEN T2.REGION_GD IN ('S', 'A', 'B') THEN 'High Grade'
                     ELSE 'Low Grade'
                END
        END STORE_SIZE_GD
FROM    SQL_TEST.MA_STORE T1
        ,SQL_TEST.CD_REGION T2
WHERE   T1.REGION_CD = T2.REGION_CD
- STORE의 SIZE에 대한 등급을 STORE의 지역(REGION), STORE_SIZE별로 STORE SIZE등급을 구한다.
- 이러한 중첩된 CASE는 사용자가 원하는 다양한 결과를 얻어 내는데 큰 도움이 된다.


4. DECODE와 CASE

DECODE와 CASE 함수는 SQL 문장에서 조건에 해당하는 값을 추출하고자 할 때 주로 사용한다


(1) DECODE

- DECODE 함수는 조건에 따라 데이터를 다른 값이나 컬럼값으로 추출 할 수 있다.

- DECODE(VALUE, IF1, THEN1, IF2, THEN2...) 형태로 사용 할 수 있다.

- VALUE 값이 IF1일 경우에 THEN1 값을 반환하고, VALUE 값이 IF2일 경우에는 THEN2 값을 반환한다.

- DECODE 함수 안에 DECODE함수를 중첩으로 사용 할 수 있다.

아래는 DECODE 함수의 일반적인 예제이다.


- 부서번호가 10이면 ACCOUNTING, 20이면 RESEARCH, 30이면 SALES

- 나머지는 OPERATIONS를 출력하는 예제

SELECT deptno, DECODE(deptno, 10 , 'ACCOUNTING' ,

                              20 , 'RESEARCH' ,

                              30 , 'SALES', 'OPERATIONS') name

FROM dept;

DEPTNO   NAME

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

    10    ACCOUNTING

    20    RESEARCH

    30    SALES

    40    OPERATIONS


아래는 DECODE 함수에서 집계 함수를 사용한 예제이다

-- 10부서는 급여합계를, 20부서는 최대값을, 30부서는 최소값을 출력하는 예제

SELECT deptno, DECODE(deptno, 10 , SUM(sal),

                              20 , MAX(sal),

                              30 , MIN(sal)) sal

 FROM emp

 GROUP BY deptno; 

 DEPTNO        SAL

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

      30          950

      20          3000

      10          8750 


DECODE함수는 집계함수와 함께 통계 데이터를 추출할 때 많이 사용한다. 아래는 부서별로 급여합계를 조회하는 예이다

-- 부서별로 급여 합계를 출력한다. 

SELECT deptno, NVL(SUM(DECODE(deptno, 10, sal)),0) deptno10, 

               NVL(SUM(DECODE(deptno, 20, sal)),0) deptno20,

               NVL(SUM(DECODE(deptno, 30, sal)),0) deptno30,

               NVL(SUM(DECODE(deptno, 40, sal)),0) deptno40

FROM emp

GROUP BY deptno;  

DEPTNO   DEPTNO10   DEPTNO20   DEPTNO30   DEPTNO40

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

     30            0             0               9400             0

     20            0             10875        0                  0

     10         8750           0               0                  0 


아래 부서별 급여합계 예를 보면 일반적인 집계함수를 사용할 때는 급여 합계가 행으로 조회가 되지만, DECODE와 MAX함수를 사용하면 열로 값을 표시할 수 있다.

-- 부서별로 급여 합계를 행으로 출력한다. 

SELECT d.deptno, NVL(SUM(e.sal),0) sal

FROM emp e, dept d

WHERE e.deptno(+) = d.deptno

GROUP BY d.deptno; 

DEPTNO        SAL

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

      10         8750

      20        10875

      30        9400

      40             0

 

-- 부서별로 급여 합계를  열로 출력한다. 

SELECT MAX(NVL(SUM(DECODE(deptno, 10, sal)),0)) deptno10, 

       MAX(NVL(SUM(DECODE(deptno, 20, sal)),0)) deptno20,

       MAX(NVL(SUM(DECODE(deptno, 30, sal)),0)) deptno30,

       MAX(NVL(SUM(DECODE(deptno, 40, sal)),0)) deptno40

 FROM emp

 GROUP BY deptno; 

DEPTNO10   DEPTNO20   DEPTNO30   DEPTNO40

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

    8750         10875              9400            0


(2) CASE

- CASE 함수는 DECODE함수가 제공하지 못하는 비교연산의 단점을 해결할 수 있는 함수이다.

- DECODE함수에서 비교연산을 수행하기 위해서는 GREATEST, LEAST등의 함수를 사용해야 하지만, CASE함수에서는 조건 연산자를 모두 사용 할 수 있다.

- CASE함수는 IF.. THEN .. ELSE 구문과 비슷 하다. WHEN절 다음에 여러 조건이 올 수 있다.


-아래의  DECODE예제를 CASE함수로 변환한 예이다. 

SELECT deptno, 

       CASE deptno

         WHEN 10 THEN 'ACCOUNTING'

         WHEN 20 THEN 'RESEARCH'

         WHEN 30 THEN 'SALES'

         ELSE 'OPERATIONS'

       END as "Dept Name"

FROM dept; 

DEPTNO  Dept Name

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

     10     ACCOUNTING

     20     RESEARCH

     30     SALES

     40     OPERATIONS 


- 아래는 WHEN절 다음에 연산자가 오는 예제이다.

-급여별로 인상율을 다르게 계산하였다. 

SELECT ename ,

       CASE

          WHEN sal < 1000  THEN sal+(sal*0.8)

          WHEN sal BETWEEN 1000 AND 2000 THEN sal+(sal*0.5)

          WHEN sal BETWEEN 2001 AND 3000 THEN sal+(sal*0.3)

          ELSE sal+(sal*0.1)

       END sal

FROM emp; 



'Server > DBMS' 카테고리의 다른 글

[DBMS_Oracle] 뷰 3  (0) 2014.12.15
[DBMS_Oracle] 뷰 2  (0) 2014.12.15
[DBMS_Oracle] 뷰 1  (0) 2014.12.15
[DBMS_MySQL] MySQL 설치 및 사용자 추가,권한  (0) 2014.12.13
[DBMS_Oracle] 인덱스  (0) 2014.12.10