본문 바로가기

Oracle/SQL

SQL 단일행 함수 - 일반함수 ( Decode )

decode (if 문으로 구현 하고 싶을때)

= (부등호) 비교만 가능하다.

decode 의 뜻 : 코드가 없고, sql 함수로만 구현하겠다.

없는 컬럼을 기존에 있던 컬럼들을 조합하거나 연산자 식을 이용하여 컬럼을 새로 생성해주는것 (파생컬럼생성) 라고 생각하면된다.

 

예제 : 이름, 부서번호, 보너스 출력 , 보너스가 부서번호 10이면 300, 20이면 400 나머지 부서번호는 0 으로 출력

보너스 라는 컬럼은 없는데 새로운 데이터를 위해 생성하여 출력해야하기때문에

→파생변수 (= 파생컬럼) 이라고 칭한다.

예를 들자면 학생들이 이해하기 쉽게 책의 내용을 요약한다거나 한다는 의미 

emp 테이블에서 보너스라는 컬럼을 만들어 내려면 decode 라는 함수를 사용해야한다.

select ename, deptno , decode(deptno, 10, 300, 20, 400, 0) as 보너스
from emp;

→부서번호가 10번이면 300 20번이면 400 그리고 나머지는 0 을 출력 해라 라는 의미

 

문제 : 우리반 테이블(emp14)에 이름,통신사, 보너스 출력 , (보너스가 통신사 lg 이면 500, kt aus 100 나머지는 0) 

select ename, telecom, decode(lower(telecom), ('lg'), 500, ('kt'), 100, 0) as 보너스
from emp;

설명 : telecom 명이 소문자인지, 대문자인지 모르기 때문에... lower 로 telecom 의 컬럼을 중첩한다.

ex) (upper로도 가능 upper(telecom),'LG' ,500, 'SK',100 ,0) as 보너스 

 

문제 : 이름, 직업, 보너스 출력 보너스가 직업이 세일즈맨이면 5000 , 그렇지 않으면 0을 출력

select ename, job , decode(job, 'SALESMAN', 5000, 0 )
from emp;

식 : decode (컬럼명 , ~~~ 이면 ,출력할 값1,

                                           ~~~이면, 출력할 값2, 없거나 기본값이거나 나머지 값들)

문제 : 이름 ,입사한 년도 4자리, 보너스 출력 입사한년도가 1980 이면 9000 입사년도가 1981 년이면 8000 나머지 년도는 1000 으로 출력

select ename, to_char(hiredate, 'RRRR'),
decode (to_char(hiredate, 'RRRR'), '1980', 9000,'1981',8000, 1000) as 보너스 
from emp;

 

decode문의 버그 (bug) '금융계열 현업 사례'

이름, 월급, 직업, 보너스를 출력하는데, 보너스가 높은 사원부터 출력 하시오.

select ename, sal, job, decode(job, 'PRESIDENT', null, sal) as 보너스
from emp;
order by 보너스 desc;

→ 해당 sql 은 버그코드 (오류)이다. 

설명 : decode 의 세번째 인자값의 따라서 네번째 인자값의 데이터 유형이 결정이 되는데,

세번째 인자값이 null 이면 문자형 입니다. (두번째 인자값의 영향을 받았기때문)

    그래서 네번째 인자값인 sal 이 문자형이 되어버렸습니다.

     암시적 형변환이 내부적으로 발생한 것입니다.

    그래서 sal 이 문자형으로 취급되어  950 이 맨 위로 올라가게 되었습니다.(9가 문자형으로 취급되면 높은 수로 취급되기때문)

→ 해결 쿼리는?

select ename, sal, job, decode (job, 'PRESIDENT', to_number(null), sal) as 보너스
from emp
order by 보너스 desc nulls last ;

→ null 을 숫자형으로 돌려주었다.