SQL초보에서 Schema Objects까지
4.3 변환 함수(Conversion Function)
변환함수는 숫자, 문자, 날짜 형 사이의 변환을 수행하는 함수이다. 여러 종류가 있지만 자주 사
용되는 변환 함수 몇 가지에 대해 알아보자.
CHARTOROWID(char) : VARCHAR2 또는 CHAR Type을 ROWID Type으로 변환 한다.
TO_CHAR(datetime|number [,fmt]) : 숫자나 날짜형 자료를 fmt 형식에 맞춰 문자로 변환 한다.
TO_DATE(char, [,fmt]) : fmt 형식의 문자를 Date값으로 변환 한다.
TO_NUMBER(char [,fmt]) : 숫자형태의 문자 char를 숫자로 변환 한다.
[TO_CHAR, TO_DATE에서 사용할 수 있는 Format 형식]
YYYY or SYYYY : 년도를 지칭하며 S를 앞에 붙이면 기원전 년도인 경우 ‘-‘가 붙음
YYY or YY or Y : 년도의 마지막 3자리, 2자리, 한자리
IYYY : 4자리의 ISO 표준 년도 형식
SYEAR or YEAR : 영문으로 표기된 년도를 표시, 앞에 S가 붙으면 기원전 년도인 경우 ‘-‘가 앞에
붙음)
Q : 분기
MM : 월
MONTH or MON : 월의 영문 표기(9자리) 또는 3자리의 단축 표기
RM : 로마숫자 월
DDD or DD or D : 년,월,주의 몇번째 날 인가를 보여줌
WW or W : 년,월에서 오늘이 몇번째 주 인가를 보여줌
DAY or DY : 요일 명칭 또는 3자리의 단축형
AM or FM : 오전과 오후 표시
HH or HH12 : 시각(1~12)
HH24 : 시각(0~23)
MI : 분
SS : 초
[접미사]
TH : 서수로 표시(DDTH라고 하면 4TH와 같은 형식으로 나타남)
SP : 숫자를 철자로 보여준다.(DDSP  FOUR)
SPTH or THSP : 서수를 철자로 보여준다.(DDSPTH  FOURTH)
[숫자를 문자로 변환 할 때 사용하는 Format 형식]
9 : 숫자의 출력
0 : 숫자가 없는 경우 0을 표시, 숫자가 있으면 숫자를 표시
. : 소수점 자리 표시
, : 콤마 자리 표시
우선 EMP 테이블에서 이름이 ‘SMITH’인 사원의 ROWID를 알아낸 후 ROWID를 이용하여 검색하
자.
SQL> select ename, sal, rowid from emp
2 where ename = 'SMITH';
ENAME SAL ROWID
---------- ---------- ------------------
SMITH 800 AAAHW7AABAAAMUiAAA
SQL> select ename, sal from emp
2 where rowid = CHARTOROWID('AAAHW7AABAAAMUiAAA');
ENAME SAL
---------- ----------
SMITH 800
SQL> select to_char(sysdate, 'YYYY/MM/DD') from dual;
TO_CHAR(SY
----------
2014/09/09
SQL> select to_char(8000000, '999,999,999') from dual;
TO_CHAR(8000
------------
8,000,000
SQL> select to_number('8000000'), to_number('8,000,000','9,999,999') from dual;
TO_NUMBER('8000000') TO_NUMBER('8,000,000','9,999,999')
-------------------- ----------------------------------
8000000 8000000
--오늘을 2014년 9월8일 이라고 한다면 2003년1월1일부터 오늘까지 몇 일 차이가 나는지 확인하
기 위해서는 아래와 같이 하면 된다.
SQL> select sysdate,
2 round(sysdate - to_date('2003.01.01','yyyy.mm.dd'))
3 from dual;
SYSDATE ROUND(SYSDATE-TO_DATE('2003.01.01','YYYY.MM.DD'))
---------- -------------------------------------------------
14/09/08 4269
-- 년중, 월중, 주중 오늘이 몇번째 일자인지를 확인 하는 예문
SQL> select to_char(sysdate, 'ddd') "1년중 몇일?",
2 to_char(sysdate, 'dd') "월의 몇번째 일?",
3 to_char(sysdate, 'd') "주중 몇번째 일?"
4 from dual;
1년 월
--- -- -
250 08 2
--아래 예문은 Format 문자를 사용하는 예이다.
SQL> select to_char(sysdate, 'YEAR MONTH DD DAY HH24:MI:SS') from dual;
TO_CHAR(SYSDATE,'YEARMONTHDDDAYHH24:MI:SS')
-----------------------------------------------------------------------
TWENTY FOURTEEN 9월 07 일요일 16:30:29
-- 문자열 그대로 출력을 원한다면 “”로 싸 주면 된다.
SQL> select ename, sal, to_char(hiredate, 'mon "the" ddth "of" yyyy') hiredate
2 from emp;
ENAME SAL HIREDATE
---------- ---------- -------------------------
SMITH 800 12월 the 17th of 1980
ALLEN 1600 2월 the 20th of 1981
WARD 1250 2월 the 22nd of 1981
JONES 2975 4월 the 02nd of 1981
MARTIN 1250 9월 the 28th of 1981
……
SQL> select ename, hiredate from emp
2 where hiredate = to_date('12월 17 80','month dd rr');
ENAME HIREDATE
---------- --------
SMITH 80/12/17
SQL> select ename, hiredate from emp
2 where hiredate = to_date('12월 17 80','month dd yy');
선택된 레코드가 없습니다.
-- 아래에서 YY와 RR 포맷의 차이에 대해 이해하자.
-- RR포맷은 오라클에서 Y2K 해결을 위해 도입했는데,
--현재년도가 2000~2049년 경우 처리연도가 00~49인 경우의 예를 들면…
-- YY포맷은 2000~2049로 인식하고 RR포맷 역시 2000~2049로 인식한다.
--현재년도가 2000~2049년인경우 처리연도가 50~99인 경우의 예를 들면…
-- YY포맷은 2050~2099로 인식하고 RR포맷은 1950~1999로 인식한다.
SQL> select to_date('12월 17 80','month dd yy') from dual;
TO_DATE(
--------
80/12/17
SQL> select to_date('12월 17 80','month dd rr') from dual;
TO_DATE(
--------
80/12/17
SQL> SELECT TO_CHAR(TO_DATE('99/01/01','RR/MM/DD'),'YYYY.MM.DD') FROM DUAL;
TO_CHAR(TO
----------
1999.01.01
SQL> SELECT TO_CHAR(TO_DATE('99/01/01','YY/MM/DD'),'YYYY.MM.DD') FROM DUAL;
TO_CHAR(TO
----------
2099.01.01
묵시적 형 변환
WHERE절 등에서 비교 타입이 다른 경우 내부적으로 타입 변환을 한다.
WHERE절에 숫자 = 문자 와 같은 비교연산을 수행 시 내부적으로 숫자를 기준으로 묵시적 변환
을 시도한다.
SQL> desc myemp1
이름 널? 유형
----------------------------------------- -------- ---------------
EMPNO NOT NULL NUMBER
ENAME VARCHAR2(100)
DEPTNO VARCHAR2(1)
ADDR VARCHAR2(100)
SAL NUMBER
SUNGBYUL VARCHAR2(1)
--empno는 primary key 인덱스, deptno에도 인덱스가 생성되어 있다.
--WHERE절의 비교대상 칼럼의 데이터 타입이 “숫자=문자” 와 같이 다르면 숫자로 자동 형 변환
된다. Deptno 칼럼의 데이터타입은 VARCHAR2 이다. “where deptno = 숫자”의 경우 deptno 칼럼
을 숫자로 변환을 하게 되므로 인덱스가 있더라도 사용이 안 된다.(인덱스 칼럼에 변형이 생김으
로 인덱스 사용불가)
SQL> desc myemp1
이름 널? 유형
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER
ENAME VARCHAR2(100)
DEPTNO VARCHAR2(1)
ADDR VARCHAR2(100)
SAL NUMBER
SUNGBYUL VARCHAR2(1)
HIREDATE DATE
OUTDATE VARCHAR2(8)
-- SQL문의 실행 시간을 표시
SQL> set timing on
SQL> select count(*) from myemp1;
COUNT(*)
----------
20000004
경 과: 00:00:06.93
-- deptno 칼럼에 인덱스를 생성하자.
SQL> create index idx_myemp1_deptno on myemp1(deptno);
인덱스가 생성되었습니다.
-- deptno 칼럼이 VARCHAR2이므로 인덱스를 이용하여 결과가 빨리 나온다.
SQL> select count(*) from myemp1
2 where deptno = '3';
COUNT(*)
----------
5000001
경 과: 00:00:00.35
-- 묵시적으로 deptno칼럼을 숫자로 변환하므로 인덱스 이용불가, 느리다.
SQL> select count(*) from myemp1
2 where deptno = 3;
COUNT(*)
----------
5000001
경 과: 00:00:22.42
-- 결국 위 쿼리는 아래와 같은 변환을 하는 것이다.
SQL> select count(*) from myemp1
2 where to_number(deptno) = 3;
COUNT(*)
----------
5000001
경 과: 00:00:23.10
4.4 일반 함수 및 조건식(General Functions and Conditional
Expressions)
NVL(expr1, expr2) : IF expr1 IS NULL expr2 ELSE expr1, expr1과 expr2의 DataType이 다르면 expr2
를 비교전 expr1로 변환 한다.
NVL2(expr1, expr2, expr3): IF expr1 IS NULL THEN expr3 ELSE expr2, expr1은 어떠한 DataType 이
라도 가능하며 expr2 및 expr3의 경우 LONG을 제외한 DataType이면 된다. 만약 expr2와 espr3가
DataType이 다르다면 비교전에 expr3을 expr2로 변환 한다.
--> 아래 예문은 NVL함수 안의 표현식의 형이 다르므로 오류가 발생 한다.
SQL> select ename, nvl(comm, 'NOT APPLICABLE') "COMMISSION"
2 from emp
3 where deptno=30;
select ename, nvl(comm, 'NOT APPLICABLE') "COMMISSION"
*
1행에 오류:
ORA-01722: 수치가 부적합합니다
SQL> 1 select ename, nvl(to_char(comm), 'NOT APPLICABLE') "COMMISSION"
SQL> /
ENAME COMMISSION
---------- ----------------------------------------
ALLEN 300
WARD 500
MARTIN 1400
BLAKE NOT APPLICABLE
TURNER 0
JAMES NOT APPLICABLE
6 개의 행이 선택되었습니다.
SQL> select ename, sal, comm, nvl2(to_char (comm), ‘sal and comm', ‘sal’) income
2 from emp
3 where deptno = 20;
ENAME SAL COMM INCOME
---------- ---------- ---------- ------------
SMITH 800 96 SAL AND COMM
JONES 2975 SAL
SCOTT 3000 SAL
ADAMS 1100 SAL
FORD 3000 SAL
--10번 부서의 사원 중 수당을 받는 사람은 급여(sal)와 수당(comm)을 더한 값을 출력하고 수당
을 받지 않는 사원은 급여만 총액으로 출력하라.
SQL> select ename, sal, comm, nvl2(comm, sal+comm ,sal) "total" from emp
2 where deptno = 10;
ENAME SAL COMM total
---------- ---------- ---------- ----------
CLARK 2450 2450
KING 5000 5000
MILLER 1300 1300
DECODE (column|expr1, search1, result1 [,search2,result2,,,][,default return]) : column1이 search1과
같으면 result1, search2와 같으면 result2 아무것도 같지 않으면 default return을 돌려 주며 4개
이상의 아규먼트로 이루어 진다.
CASE: DECODE 함수와 기능이 비슷하지만 좀더 직관적인 함수이다.
SQL> select ename, decode(deptno, 10, 'Accounting',
2 20, 'Research',
3 30, 'Sales',
4 40, 'Operations',
5 'Unknown') department
6 from emp
7 /
--> 아래의 CASE 함수와 동일한 결과가 나타난다.
SQL> select ename,
2 (case deptno
3 when 10 then 'Accounting'
4 when 20 then 'Research'
5 when 30 then 'Sales'
6 when 40 then 'Operations'
7 else 'Unknown'
8 end) department
9 from emp
10 /
ENAME DEPARTMENT
---------- ----------
SMITH Research
ALLEN Sales
……
16 개의 행이 선택되었습니다.
--> 10번 부서의 급여 평균이 800보다 크면 ‘H’, 작으면 ‘L’을 출력해 보자.
SQL> select case
2 when (select avg(sal) from emp where deptno=10) >= 800 then 'H'
3 else 'L'
4 end "급여수준"
5 from dual;
-
H
with a as (
select avg(sal) avg from emp
where deptno = 10
)
select DECODE(SIGN(a.avg - 800), 1, 'H', -1, 'L', 'UnKnown')
from a;
SQL> SELECT ename,
2 (CASE EXTRACT(YEAR FROM hiredate)
3 WHEN 1982 THEN '8 years service'
4 WHEN 1981 THEN '9 years service'
5 WHEN 1980 THEN '10 years service'
6 END) AS "Award for 2000"
7 FROM emp
8 WHERE EXTRACT(YEAR FROM hiredate) IN (1982,1981,1980)
9 ORDER BY hiredate
10 /
ENAME Award for 2000
---------- ----------------
SMITH 10 years service
ALLEN 9 years service
WARD 9 years service
JONES 9 years service
……
SQL> SELECT empno, ename,(CASE
2 WHEN sal >= 5000 THEN 'High Sal'
3 WHEN sal >= 3000 AND sal < 5000 THEN 'Middle Sal'
4 WHEN sal >= 1000 AND sal < 3000 THEN 'Average Sal'
5 WHEN sal < 1000 THEN 'Low Sal'
6 END) AS Sal_Category
7 FROM emp;
EMPNO ENAME SAL_CATEGOR
---------- ---------- -----------
7369 SMITH Low Sal
7499 ALLEN Average Sal
7521 WARD Average Sal
7566 JONES Average Sal
……
NULLIF (expr1, expr2) : expr1과 expr2가 같은면 NULL. 같지 않으면 expr1을 리턴 한다.
SQL> select nvl(nullif('ORACLE','oracle'),'널입니다')from dual;
NVL(NULL
--------
ORACLE
- 수당이 NULL인 사원은 SAL를, NULL이 아니면 sal+comm을 nullif, nvl2를 이용하여 출력하시오.
SQL> select sal, comm, nvl2(nullif(sal, nvl(comm, 0)+sal),sal+comm,sal) from emp;
SAL COMM NVL2(NULLIF(SAL,NVL(COMM,0)+SAL),SAL+COMM,SAL)
---------- ---------- ----------------------------------------------
800 800
1600 300 1900
1250 500 1750
2975 2975
1250 1400 2650
2850 2850
2450 2450
……
COALESCE (expr1, expr2,,,,) : 여러 expr중 처음 NULL 아닌 요소를 리턴 한다.
GREATEST (expr1, expr2,,,,) : 여러 expr중 최대인 것을 리턴 한다.
LEAST (expr1, expr2,,,,) : 여러 expr중 최소인 것을 리턴 한다.
-- EMP테이블에서 COMM이 NULL이 아니면 COMM을 출력, COMM이 NULL이고 SAL가 NULL이
아니면 SAL 출력, SAL, COMM모두 NULL이면 0을 출력하시오.
SQL> select ename, sal, comm, coalesce(comm, sal, 0) from emp;
ENAME SAL COMM COALESCE(COMM,SAL,0)
---------- ---------- ---------- --------------------
SMITH 800 800
ALLEN 1600 300 300
WARD 1250 500 500
JONES 2975 2975
MARTIN 1250 1400 1400
BLAKE 2850 2850
CLARK 2450 2450
SCOTT 3000 3000
KING 5000 5000
TURNER 1500 0 0
ADAMS 1100 1100
SQL> select greatest(1,6,8,5,3,4) from dual;
GREATEST(1,6,8,5,3,4)
---------------------
8
SQL> select greatest('B','T','W') from dual;
G
-
W
SQL> select least(1,6,8,5,3,4) from dual;
LEAST(1,6,8,5,3,4)
------------------
1
SQL> select least('B','T','W') from dual;
L
-
B
USER : 현재 세션의 접속한 USER계정을 VARCHAR2 형식으로 리턴 한다.
SQL> select USER from dual;
USER
------------------------------
SCOTT
SQL> show user;
USER은 "SCOTT"입니다
VSIZE(expr) : expr의 바이트 수를 리턴 한다.
SQL> select vsize(empno), vsize(ename) from emp;
VSIZE(EMPNO) VSIZE(ENAME)
------------ ------------
3 5
3 5
3 4

#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)

  • 1.
    SQL초보에서 Schema Objects까지 4.3변환 함수(Conversion Function) 변환함수는 숫자, 문자, 날짜 형 사이의 변환을 수행하는 함수이다. 여러 종류가 있지만 자주 사 용되는 변환 함수 몇 가지에 대해 알아보자. CHARTOROWID(char) : VARCHAR2 또는 CHAR Type을 ROWID Type으로 변환 한다. TO_CHAR(datetime|number [,fmt]) : 숫자나 날짜형 자료를 fmt 형식에 맞춰 문자로 변환 한다. TO_DATE(char, [,fmt]) : fmt 형식의 문자를 Date값으로 변환 한다. TO_NUMBER(char [,fmt]) : 숫자형태의 문자 char를 숫자로 변환 한다. [TO_CHAR, TO_DATE에서 사용할 수 있는 Format 형식] YYYY or SYYYY : 년도를 지칭하며 S를 앞에 붙이면 기원전 년도인 경우 ‘-‘가 붙음 YYY or YY or Y : 년도의 마지막 3자리, 2자리, 한자리 IYYY : 4자리의 ISO 표준 년도 형식 SYEAR or YEAR : 영문으로 표기된 년도를 표시, 앞에 S가 붙으면 기원전 년도인 경우 ‘-‘가 앞에 붙음) Q : 분기 MM : 월 MONTH or MON : 월의 영문 표기(9자리) 또는 3자리의 단축 표기 RM : 로마숫자 월 DDD or DD or D : 년,월,주의 몇번째 날 인가를 보여줌 WW or W : 년,월에서 오늘이 몇번째 주 인가를 보여줌 DAY or DY : 요일 명칭 또는 3자리의 단축형 AM or FM : 오전과 오후 표시 HH or HH12 : 시각(1~12) HH24 : 시각(0~23) MI : 분 SS : 초 [접미사] TH : 서수로 표시(DDTH라고 하면 4TH와 같은 형식으로 나타남) SP : 숫자를 철자로 보여준다.(DDSP  FOUR) SPTH or THSP : 서수를 철자로 보여준다.(DDSPTH  FOURTH)
  • 2.
    [숫자를 문자로 변환할 때 사용하는 Format 형식] 9 : 숫자의 출력 0 : 숫자가 없는 경우 0을 표시, 숫자가 있으면 숫자를 표시 . : 소수점 자리 표시 , : 콤마 자리 표시 우선 EMP 테이블에서 이름이 ‘SMITH’인 사원의 ROWID를 알아낸 후 ROWID를 이용하여 검색하 자. SQL> select ename, sal, rowid from emp 2 where ename = 'SMITH'; ENAME SAL ROWID ---------- ---------- ------------------ SMITH 800 AAAHW7AABAAAMUiAAA SQL> select ename, sal from emp 2 where rowid = CHARTOROWID('AAAHW7AABAAAMUiAAA'); ENAME SAL ---------- ---------- SMITH 800 SQL> select to_char(sysdate, 'YYYY/MM/DD') from dual; TO_CHAR(SY ---------- 2014/09/09 SQL> select to_char(8000000, '999,999,999') from dual; TO_CHAR(8000 ------------ 8,000,000 SQL> select to_number('8000000'), to_number('8,000,000','9,999,999') from dual; TO_NUMBER('8000000') TO_NUMBER('8,000,000','9,999,999') -------------------- ---------------------------------- 8000000 8000000
  • 3.
    --오늘을 2014년 9월8일이라고 한다면 2003년1월1일부터 오늘까지 몇 일 차이가 나는지 확인하 기 위해서는 아래와 같이 하면 된다. SQL> select sysdate, 2 round(sysdate - to_date('2003.01.01','yyyy.mm.dd')) 3 from dual; SYSDATE ROUND(SYSDATE-TO_DATE('2003.01.01','YYYY.MM.DD')) ---------- ------------------------------------------------- 14/09/08 4269 -- 년중, 월중, 주중 오늘이 몇번째 일자인지를 확인 하는 예문 SQL> select to_char(sysdate, 'ddd') "1년중 몇일?", 2 to_char(sysdate, 'dd') "월의 몇번째 일?", 3 to_char(sysdate, 'd') "주중 몇번째 일?" 4 from dual; 1년 월 --- -- - 250 08 2 --아래 예문은 Format 문자를 사용하는 예이다. SQL> select to_char(sysdate, 'YEAR MONTH DD DAY HH24:MI:SS') from dual; TO_CHAR(SYSDATE,'YEARMONTHDDDAYHH24:MI:SS') ----------------------------------------------------------------------- TWENTY FOURTEEN 9월 07 일요일 16:30:29 -- 문자열 그대로 출력을 원한다면 “”로 싸 주면 된다. SQL> select ename, sal, to_char(hiredate, 'mon "the" ddth "of" yyyy') hiredate 2 from emp; ENAME SAL HIREDATE ---------- ---------- ------------------------- SMITH 800 12월 the 17th of 1980 ALLEN 1600 2월 the 20th of 1981 WARD 1250 2월 the 22nd of 1981 JONES 2975 4월 the 02nd of 1981 MARTIN 1250 9월 the 28th of 1981
  • 4.
    …… SQL> select ename,hiredate from emp 2 where hiredate = to_date('12월 17 80','month dd rr'); ENAME HIREDATE ---------- -------- SMITH 80/12/17 SQL> select ename, hiredate from emp 2 where hiredate = to_date('12월 17 80','month dd yy'); 선택된 레코드가 없습니다. -- 아래에서 YY와 RR 포맷의 차이에 대해 이해하자. -- RR포맷은 오라클에서 Y2K 해결을 위해 도입했는데, --현재년도가 2000~2049년 경우 처리연도가 00~49인 경우의 예를 들면… -- YY포맷은 2000~2049로 인식하고 RR포맷 역시 2000~2049로 인식한다. --현재년도가 2000~2049년인경우 처리연도가 50~99인 경우의 예를 들면… -- YY포맷은 2050~2099로 인식하고 RR포맷은 1950~1999로 인식한다. SQL> select to_date('12월 17 80','month dd yy') from dual; TO_DATE( -------- 80/12/17 SQL> select to_date('12월 17 80','month dd rr') from dual; TO_DATE( -------- 80/12/17 SQL> SELECT TO_CHAR(TO_DATE('99/01/01','RR/MM/DD'),'YYYY.MM.DD') FROM DUAL; TO_CHAR(TO ---------- 1999.01.01 SQL> SELECT TO_CHAR(TO_DATE('99/01/01','YY/MM/DD'),'YYYY.MM.DD') FROM DUAL;
  • 5.
    TO_CHAR(TO ---------- 2099.01.01 묵시적 형 변환 WHERE절등에서 비교 타입이 다른 경우 내부적으로 타입 변환을 한다. WHERE절에 숫자 = 문자 와 같은 비교연산을 수행 시 내부적으로 숫자를 기준으로 묵시적 변환 을 시도한다. SQL> desc myemp1 이름 널? 유형 ----------------------------------------- -------- --------------- EMPNO NOT NULL NUMBER ENAME VARCHAR2(100) DEPTNO VARCHAR2(1) ADDR VARCHAR2(100) SAL NUMBER SUNGBYUL VARCHAR2(1) --empno는 primary key 인덱스, deptno에도 인덱스가 생성되어 있다. --WHERE절의 비교대상 칼럼의 데이터 타입이 “숫자=문자” 와 같이 다르면 숫자로 자동 형 변환 된다. Deptno 칼럼의 데이터타입은 VARCHAR2 이다. “where deptno = 숫자”의 경우 deptno 칼럼 을 숫자로 변환을 하게 되므로 인덱스가 있더라도 사용이 안 된다.(인덱스 칼럼에 변형이 생김으 로 인덱스 사용불가) SQL> desc myemp1 이름 널? 유형 ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER ENAME VARCHAR2(100) DEPTNO VARCHAR2(1) ADDR VARCHAR2(100) SAL NUMBER SUNGBYUL VARCHAR2(1)
  • 6.
    HIREDATE DATE OUTDATE VARCHAR2(8) --SQL문의 실행 시간을 표시 SQL> set timing on SQL> select count(*) from myemp1; COUNT(*) ---------- 20000004 경 과: 00:00:06.93 -- deptno 칼럼에 인덱스를 생성하자. SQL> create index idx_myemp1_deptno on myemp1(deptno); 인덱스가 생성되었습니다. -- deptno 칼럼이 VARCHAR2이므로 인덱스를 이용하여 결과가 빨리 나온다. SQL> select count(*) from myemp1 2 where deptno = '3'; COUNT(*) ---------- 5000001 경 과: 00:00:00.35 -- 묵시적으로 deptno칼럼을 숫자로 변환하므로 인덱스 이용불가, 느리다. SQL> select count(*) from myemp1 2 where deptno = 3; COUNT(*) ---------- 5000001 경 과: 00:00:22.42
  • 7.
    -- 결국 위쿼리는 아래와 같은 변환을 하는 것이다. SQL> select count(*) from myemp1 2 where to_number(deptno) = 3; COUNT(*) ---------- 5000001 경 과: 00:00:23.10 4.4 일반 함수 및 조건식(General Functions and Conditional Expressions) NVL(expr1, expr2) : IF expr1 IS NULL expr2 ELSE expr1, expr1과 expr2의 DataType이 다르면 expr2 를 비교전 expr1로 변환 한다. NVL2(expr1, expr2, expr3): IF expr1 IS NULL THEN expr3 ELSE expr2, expr1은 어떠한 DataType 이 라도 가능하며 expr2 및 expr3의 경우 LONG을 제외한 DataType이면 된다. 만약 expr2와 espr3가 DataType이 다르다면 비교전에 expr3을 expr2로 변환 한다. --> 아래 예문은 NVL함수 안의 표현식의 형이 다르므로 오류가 발생 한다. SQL> select ename, nvl(comm, 'NOT APPLICABLE') "COMMISSION" 2 from emp 3 where deptno=30; select ename, nvl(comm, 'NOT APPLICABLE') "COMMISSION" * 1행에 오류: ORA-01722: 수치가 부적합합니다 SQL> 1 select ename, nvl(to_char(comm), 'NOT APPLICABLE') "COMMISSION" SQL> / ENAME COMMISSION ---------- ---------------------------------------- ALLEN 300 WARD 500 MARTIN 1400
  • 8.
    BLAKE NOT APPLICABLE TURNER0 JAMES NOT APPLICABLE 6 개의 행이 선택되었습니다. SQL> select ename, sal, comm, nvl2(to_char (comm), ‘sal and comm', ‘sal’) income 2 from emp 3 where deptno = 20; ENAME SAL COMM INCOME ---------- ---------- ---------- ------------ SMITH 800 96 SAL AND COMM JONES 2975 SAL SCOTT 3000 SAL ADAMS 1100 SAL FORD 3000 SAL --10번 부서의 사원 중 수당을 받는 사람은 급여(sal)와 수당(comm)을 더한 값을 출력하고 수당 을 받지 않는 사원은 급여만 총액으로 출력하라. SQL> select ename, sal, comm, nvl2(comm, sal+comm ,sal) "total" from emp 2 where deptno = 10; ENAME SAL COMM total ---------- ---------- ---------- ---------- CLARK 2450 2450 KING 5000 5000 MILLER 1300 1300 DECODE (column|expr1, search1, result1 [,search2,result2,,,][,default return]) : column1이 search1과 같으면 result1, search2와 같으면 result2 아무것도 같지 않으면 default return을 돌려 주며 4개 이상의 아규먼트로 이루어 진다. CASE: DECODE 함수와 기능이 비슷하지만 좀더 직관적인 함수이다. SQL> select ename, decode(deptno, 10, 'Accounting', 2 20, 'Research', 3 30, 'Sales', 4 40, 'Operations',
  • 9.
    5 'Unknown') department 6from emp 7 / --> 아래의 CASE 함수와 동일한 결과가 나타난다. SQL> select ename, 2 (case deptno 3 when 10 then 'Accounting' 4 when 20 then 'Research' 5 when 30 then 'Sales' 6 when 40 then 'Operations' 7 else 'Unknown' 8 end) department 9 from emp 10 / ENAME DEPARTMENT ---------- ---------- SMITH Research ALLEN Sales …… 16 개의 행이 선택되었습니다. --> 10번 부서의 급여 평균이 800보다 크면 ‘H’, 작으면 ‘L’을 출력해 보자. SQL> select case 2 when (select avg(sal) from emp where deptno=10) >= 800 then 'H' 3 else 'L' 4 end "급여수준" 5 from dual; - H with a as ( select avg(sal) avg from emp where deptno = 10 ) select DECODE(SIGN(a.avg - 800), 1, 'H', -1, 'L', 'UnKnown') from a;
  • 10.
    SQL> SELECT ename, 2(CASE EXTRACT(YEAR FROM hiredate) 3 WHEN 1982 THEN '8 years service' 4 WHEN 1981 THEN '9 years service' 5 WHEN 1980 THEN '10 years service' 6 END) AS "Award for 2000" 7 FROM emp 8 WHERE EXTRACT(YEAR FROM hiredate) IN (1982,1981,1980) 9 ORDER BY hiredate 10 / ENAME Award for 2000 ---------- ---------------- SMITH 10 years service ALLEN 9 years service WARD 9 years service JONES 9 years service …… SQL> SELECT empno, ename,(CASE 2 WHEN sal >= 5000 THEN 'High Sal' 3 WHEN sal >= 3000 AND sal < 5000 THEN 'Middle Sal' 4 WHEN sal >= 1000 AND sal < 3000 THEN 'Average Sal' 5 WHEN sal < 1000 THEN 'Low Sal' 6 END) AS Sal_Category 7 FROM emp; EMPNO ENAME SAL_CATEGOR ---------- ---------- ----------- 7369 SMITH Low Sal 7499 ALLEN Average Sal 7521 WARD Average Sal 7566 JONES Average Sal …… NULLIF (expr1, expr2) : expr1과 expr2가 같은면 NULL. 같지 않으면 expr1을 리턴 한다.
  • 11.
    SQL> select nvl(nullif('ORACLE','oracle'),'널입니다')fromdual; NVL(NULL -------- ORACLE - 수당이 NULL인 사원은 SAL를, NULL이 아니면 sal+comm을 nullif, nvl2를 이용하여 출력하시오. SQL> select sal, comm, nvl2(nullif(sal, nvl(comm, 0)+sal),sal+comm,sal) from emp; SAL COMM NVL2(NULLIF(SAL,NVL(COMM,0)+SAL),SAL+COMM,SAL) ---------- ---------- ---------------------------------------------- 800 800 1600 300 1900 1250 500 1750 2975 2975 1250 1400 2650 2850 2850 2450 2450 …… COALESCE (expr1, expr2,,,,) : 여러 expr중 처음 NULL 아닌 요소를 리턴 한다. GREATEST (expr1, expr2,,,,) : 여러 expr중 최대인 것을 리턴 한다. LEAST (expr1, expr2,,,,) : 여러 expr중 최소인 것을 리턴 한다. -- EMP테이블에서 COMM이 NULL이 아니면 COMM을 출력, COMM이 NULL이고 SAL가 NULL이 아니면 SAL 출력, SAL, COMM모두 NULL이면 0을 출력하시오. SQL> select ename, sal, comm, coalesce(comm, sal, 0) from emp; ENAME SAL COMM COALESCE(COMM,SAL,0) ---------- ---------- ---------- -------------------- SMITH 800 800 ALLEN 1600 300 300 WARD 1250 500 500 JONES 2975 2975 MARTIN 1250 1400 1400 BLAKE 2850 2850 CLARK 2450 2450
  • 12.
    SCOTT 3000 3000 KING5000 5000 TURNER 1500 0 0 ADAMS 1100 1100 SQL> select greatest(1,6,8,5,3,4) from dual; GREATEST(1,6,8,5,3,4) --------------------- 8 SQL> select greatest('B','T','W') from dual; G - W SQL> select least(1,6,8,5,3,4) from dual; LEAST(1,6,8,5,3,4) ------------------ 1 SQL> select least('B','T','W') from dual; L - B USER : 현재 세션의 접속한 USER계정을 VARCHAR2 형식으로 리턴 한다. SQL> select USER from dual; USER ------------------------------ SCOTT
  • 13.
    SQL> show user; USER은"SCOTT"입니다 VSIZE(expr) : expr의 바이트 수를 리턴 한다. SQL> select vsize(empno), vsize(ename) from emp; VSIZE(EMPNO) VSIZE(ENAME) ------------ ------------ 3 5 3 5 3 4