함수(FUNCTION)
* 자바의 메소드와 같은 존재
* 전달된 값들을 읽어서 계산한 결과를 반환
* - 단일행 : N개의 값을 읽어서 N개의 결과를 리턴(매 행마다 반복적으로 함수를 실행 후 결과를 반환함.)
* - 그룹함수 : N개의 값을 읽어서 1개의 결과를 리턴(하나의 그룹별로 함수를 실행 후 결과를 반환함.)
* => 집계, 통계에 많이 씀.
*
* 주의사항
* 단일행함수는 단일행함수끼리, 그룹함수는 그룹함수끼리 사용함.(결과행의 개수가 다르기 때문)
단일행 함수(문자)
LENGTH / LENGTHB
* LENGTH(STR) : 해당 전달된 문자열의 글자 수를 반환
* LENGTHB(STR): 해당 전달되나 문자열의 바이트 수 반환
* => 결과값은 NUMBER타입으로 반환
*
* - STR : '문자열 리터럴' / 문자열에 해당하는 컬럼
* - 한글 : 'ㄱ', 'ㅣ', 'ㅁ', '김', ... => 한글자당 3BYTE
* - 숫자, 영문, 특수문자, 공백 : '!', '~', 'a', 'A', '1' => 한글자당 1BYTE
SELECT LENGTH('오라클!'), LENGTHB('오라클!')
FROM DUAL;
SELECT EMAIL, LENGTH(EMAIL), LENGTHB(EMAIL),
EMP_NAME, LENGTH(EMP_NAME), LENGTHB(EMP_NAME)
FROM EMPLOYEE;
INSTR
* 문자열로부터 특정 문자의 위치값 반환
*
* [표현법]
* INSTR(STR,'특정문자',찾을위치의시작값,순번)
* => 결과값은 NUMBER타입으로 반환
* => 찾을위치의시작값, 순번은 생략 가능
*
* 찾을 위치의 시작값
* 1 : '특정문자'를 앞에서부터 찾겠다(생략시 기본값)
* -1 : '특정문자'를 뒤에서부터 찾겠다.
*
* 순번(생략시 기본값은 1)
SELECT INSTR('AABAACAABBAA', 'B' )
FROM DUAL;
SELECT INSTR('AABAACAABBAA', 'B', -1)
FROM DUAL;
SELECT INSTR('AABAACAABBAA', 'B', 1,2)
FROM DUAL;
SELECT INSTR('AABAACAABBAA', 'B', -1, 2)
FROM DUAL;
SELECT EMAIL,INSTR(EMAIL, '@',1 ,2) AS "@의 위치"
FROM EMPLOYEE;
SUBSTR
* 문자열로부터 특정 문자열을 추출하여 반환(JAVA에서의 substring())
*
* [표현법]
* SUBSTR(STR, POSITION, LENGTH)
* => 결과값은 CHARACTER형으로 반환함.
* => LENGTH는 생략 가능(생략시, 끝까지 잘라냄)
*
* - STR : '문자열'리터럴' / 문자열 타입의 컬럼명
* - POSITION : 문자열 추출을 시작할 위치값
* - LENGTH : 추출할 문자 개수
SELECT SUBSTR('SHOWMETHEMONEY',7)
FROM DUAL;
SELECT SUBSTR('SHOWMETHEMONEY',5,2)
FROM DUAL;
SELECT SUBSTR('SHOWMETHEMONEY',1,6)
FROM DUAL;
SELECT SUBSTR('SHOWMETHEMONEY',-8,3)
FROM DUAL;
SELECT EMP_NAME, SUBSTR(EMP_NO, 8,1)AS "성별"
FROM EMPLOYEE;
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) IN ('1','3');
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) IN ('2','4');
SELECT EMP_NAME, EMAIL,SUBSTR(EMAIL,1, INSTR(EMAIL,'@')-1) AS "ID"
FROM EMPLOYEE;
LPAD / RPAD
* 제시한 문자열에 임의의 문자를 왼쪽 또는 오른쪽에 덧붙여 N길이만큼의 문자열을 반환
*
* [표현법]
* LPAD/RPAD(STR, 최종적으로 반환할 문자열의 길이(바이트), 덧붙이고자하는 문자)
* => 결과값은 CHARACTER타입으로 나옴.(문자열 형태)
* => 덧붙이고자하는 문자 부분은 생략 가능함.
*
* - STR : '문자열 리터럴', 문자열 타입의 컬럼명
SELECT LPAD(EMAIL,16,'#')
FROM EMPLOYEE;
SELECT RPAD(EMAIL, 20, '#')
FROM EMPLOYEE;
SELECT RPAD('850918-2',14,'*')
FROM DUAL;
SELECT EMP_NAME,RPAD(SUBSTR(EMP_NO,1,8),14,'*')
FROM EMPLOYEE;
LTRIM, RTRIM
* 왼쪽, 오른쪽을 기준으로 제거하고 싶은 문자를 제거함
*
* [표현법]
* LTRIM/RTRIM(STR, '제거시키고자하는문자')
* => 결과값은 CHARACTER타입으로 반환(문자열 형태)
* =>'제거시키고자하는문자'는 생략 가능(생략시 공백 제거)
*
* - STR : '문자열리터럴' / 문자열이 담긴 컬럼명
SELECT LTRIM(' K H')
FROM DUAL;
SELECT RTRIM('K H ')
FROM DUAL;
SELECT LTRIM('000123456000','0')
FROM DUAL;
SELECT RTRIM('000123456000','0')
FROM DUAL;
SELECT LTRIM('123123KH123', '123')
FROM DUAL;
SELECT LTRIM('ACABACCKH','ABC')
FROM DUAL;
SELECT LTRIM('ACABACCKH','D')
FROM DUAL;
TRIM
* 문자열의 양쪽/ 앞쪽/ 뒤쪽에 있는 특정문자를 제거한 나머지 문자열을 반환
*
* [표현법]
* TRIM(BOTH/LEADING/TRAILING '제거시키고자하는문자' FROM STR)
* => 결과값은 CHARACTER타입으로 반환(문자열 형태)
* => '제거시키고자하는문자', FROM 생략 가능
*
* - BOTH : 양쪽에 있는 해당 문자를 제거함.
* - LEADING : 앞쪽에 있는 해당 문자를 제거함.(LTRIM과 동일)
* - TRAILING : 뒤쪽에 있는 해당 문자를 제거함.(RTRIM과 동일)
* - BOTH, LEADING, TRAILING은 생략 가능(BOTH가 기본값)
* - STR : '문자열 리터럴' / 문자열 형식의 컬럼명
SELECT TRIM(' K H ')
FROM DUAL;
SELECT TRIM('Z' FROM 'ZZZKHZZZ')
FROM DUAL;
SELECT TRIM(BOTH 'Z' FROM 'ZZZBOTHZZZ')
FROM DUAL;
SELECT TRIM(LEADING 'Z' FROM 'ZZZKHZZZ')
FROM DUAL;
SELECT TRIM(TRAILING 'Z' FROM 'ZZZKHZZZ')
FROM DUAL;
LOWER / UPPER / INITCAP
* LOWER(STR) : 다 소문자로 변경
* UPPER(STR) : 다 대문자로 변경
* INITCAP(STR) : 각 단어 앞글자만 대문자로 변경(띄어쓰기 기준)
* => 결과값은 CHARACTER 타입으로 변환(문자열 형태)
*
* - STR : '문자열 리터럴' / 문자열 타입의 컬럼명
SELECT LOWER('WELCOME TO MY WORLD')
FROM DUAL;
SELECT UPPER('welcome to my world')
FROM DUAL;
SELECT INITCAP('welcome to my world')
FROM DUAL;
SELECT INITCAP('welcome to myworld')
FROM DUAL;
CONCAT
* CONCAT(STR1, STR2) : 전달된 두개의 문자열을 하나로 합친 결과를 반환
* => 결과값은 CHARACTER타입으로 반환(문자열형태)
* - STR1, STR2 : '문자열 리터럴' / 문자열 타입의 컬럼명
SELECT CONCAT('가나다','ABC')
FROM DUAL;
SELECT '가나다' || 'ABC'
FROM DUAL;
SELECT '가나다'||'ABC'||'DEF'
FROM DUAL;
SELECT CONCAT('가나다','ABC','DEF')
FROM DUAL;
SELECT CONCAT('가나다',CONCAT('ABC','DEF'))
FROM DUAL;
REPLACE
* STR로 부터 '찾을문자'를 찾아서 '바꿀문자'로 바꾼 문자열을 반환
*
* [표현법]
* REPLACE(STR,'찾을문자','바꿀문자')
* => 결과값은 CHARACTER타입으로 반환
*
* -STR : '문자열 리터럴' / 문자열 타입의 컬럼명
SELECT REPLACE('서울시 강남구 역삼동', '역삼동', '논현동')
FROM DUAL;
SELECT EMP_NAME, EMAIL, REPLACE(EMAIL,'kh.or.kr','iei.com')
FROM EMPLOYEE;
단일행 함수(숫자)
ABS
* ABS(NUMBER) : 절대값을 구해주는 함수
SELECT ABS(-10)
FROM DUAL;
SELECT ABS(-10.9)
FROM DUAL;
MOD
* MOD(NUMBER1, NUMBER2) : 두 수를 나눈 나머지값을 반환해주는 함수
SELECT MOD(10,3)
FROM DUAL;
SELECT MOD(-10,3)
FROM DUAL;
SELECT MOD(10.9, 3)
FROM DUAL;
ROUND
* ROUND(NUMBER, 위치) : 반올림처리(5이상)를 해주는 함수
* 위치 : 소수점 아래 N번째 수에서 반올림함.
* 위치는 생략 가능, 생략시 기본값은 0
SELECT ROUND(123.456)
FROM DUAL;
SELECT ROUND(123.456, 1)
FROM DUAL;
SELECT ROUND(123.456, 2)
FROM DUAL;
SELECT ROUND(123.456, 3)
FROM DUAL;
SELECT ROUND(123.456, -1)
FROM DUAL;
SELECT ROUND(123.456, -2)
FROM DUAL;
SELECT ROUND(123.456, -3)
FROM DUAL;
SELECT ROUND(123.456, -4)
FROM DUAL;
CEIL, FLOOR
* CEIL(NUMBER) : 소수점 아래의 수를 무조건 올림처리해줌.
* FLOOR(NUMBER) : 소수점 아래의 수를 무조건 버림처리해줌.
SELECT CEIL(123.156)
FROM DUAL;
SELECT FLOOR(123.956)
FROM DUAL;
SELECT FLOOR(207.68)
FROM DUAL;
SELECT EMP_NAME AS "이름", LPAD(CONCAT(FLOOR(SYSDATE - HIRE_DATE),'일'),6) AS "근무일수"
FROM EMPLOYEE;
TRUNC
* TRUNC(NUMBER, 위치) : 위치 지정가능한 버림처리를 해주는 함수
* 위치는 생략 가능, 생략시 기본값은 0(FLOOR와 같음)
* 소수점 아래의 위치까지만 남겨놓고 버림처리함.
SELECT TRUNC(123.756)
FROM DUAL;
SELECT TRUNC(123.756, 1)
FROM DUAL;
SELECT TRUNC(123.756, -1)
FROM DUAL;
단일행 함수(날짜)
MONTHS_BETWEEN
* MONTHS_BETWEEN(DATE1, DATE2) : 두 날짜 사이의 개월수 반환
* 결과값이 NUMBER타입으로 반환(일,시,분,초가 소수점으로 나옴!)
* 날짜는 미래, 과거 순서로 해줌(반대로 하면 음수가 나옴)
SELECT EMP_NAME,
FLOOR(SYSDATE - HIRE_DATE)||'일' AS "근무일수",
FLOOR(MONTHS_BETWEEN(SYSDATE, HIRE_DATE))||'개월' AS "근무개월수"
FROM EMPLOYEE;
ADD_MONTHS
* ADD_MONTHS(DATE, NUMBER) : 특정 날짜에 해당 숫자만큼의 개월수를 더한 날짜를 반환함.
* 결과값이 DATE타입으로 반환
SELECT ADD_MONTHS(SYSDATE,5)
FROM DUAL;
SELECT EMP_NAME, HIRE_DATE, ADD_MONTHS(HIRE_DATE,6)
FROM EMPLOYEE;
SELECT ADD_MONTHS(SYSDATE,-5)
FROM DUAL;
NEXT_DAY, LAST_DAY
* NEXT_DAY(DATE,요일) : 특정 날짜에서 가장 가까운 해당 요일을 찾아서 그 날짜를 반환
* => 1: 일요일, 2:월요일, 3: 화요일, ... , 6:금요일, 7:토요일
* LAST_DAY(DATE) : 특정 날짜가 속한 달의 마지막 날짜를 구해서 반환
SELECT NEXT_DAY(SYSDATE, '일요일')
FROM DUAL;
SELECT NEXT_DAY(SYSDATE,'일')
FROM DUAL;
SELECT NEXT_DAY(SYSDATE,1)
FROM DUAL;
SELECT LAST_DAY(SYSDATE)
FROM DUAL;
SELECT EMP_NAME, HIRE_DATE, LAST_DAY(HIRE_DATE)
FROM EMPLOYEE;
ALTER SESSION SET
* 현재 오라클의 언어를 바꿔주는 구문임.
ALTER SESSION SET NLS_LANGUAGE = AMERICAN;
ALTER SESSION SET NLS_LANGUAGE = KOREAN;
* EXTRACT : 년도 또느 월 또는 일 정보를 추출해서 반환
* 결과값으로 NUMBER타입을 반환함
* - EXTRACT(YEAR FROM DATE) : 특정 날짜로부터 년도만 추출
* - EXTRACT(MONTH FROM DATE) : 특정 날짜로부터 월만 추출
* - EXTRACT(DAY FROM DATE) : 특정 날짜로부터 일만 추출
SELECT EXTRACT(YEAR FROM SYSDATE),
EXTRACT(MONTH FROM SYSDATE),
EXTRACT(DAY FROM SYSDATE)
FROM DUAL;
SELECT EMP_NAME,
EXTRACT(YEAR FROM HIRE_DATE)"입사년도",
EXTRACT(MONTH FROM HIRE_DATE)"입사월",
EXTRACT(DAY FROM HIRE_DATE)"입사일"
FROM EMPLOYEE
ORDER BY "입사년도", "입사월", "입사일";
단일행 함수(형변환)
TO_CHAR
* TO_CHAR(NUMBER/ DATE, '포맷')
* NUMBER, DATE => CHARACTER
* => 숫자 또는 날짜형 데이터를 문자형 타입으로 변환
* => 반환값이 CHARACTER임.
SELECT 1234, TO_CHAR(1234)
FROM DUAL;
SELECT TO_CHAR(1234,'00000')
FROM DUAL;
SELECT TO_CHAR(1234,'99999')
FROM DUAL;
SELECT TO_CHAR(1234,'L00000')
FROM DUAL;
SELECT TO_CHAR(1234,'L99999')
FROM DUAL;
SELECT TO_CHAR(1234,'$99999')
FROM DUAL;
SELECT TO_CHAR(1234, 'L99,999')
FROM DUAL;
SELECT EMP_NAME, TO_CHAR(SALARY,'L999,999,999') AS "급여정보"
FROM EMPLOYEE;
SELECT SYSDATE
FROM DUAL;
SELECT TO_CHAR(SYSDATE)
FROM DUAL;
SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD')
FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'PM HH:MI:SS')
FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'PM HH24:MI:SS')
FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'MON DY, YYYY')
FROM DUAL;
SELECT
TO_CHAR(SYSDATE, 'YYYY'),
TO_CHAR(SYSDATE, 'RRRR'),
TO_CHAR(SYSDATE, 'YY'),
TO_CHAR(SYSDATE, 'RR'),
TO_CHAR(SYSDATE, 'YEAR')
FROM DUAL;
SELECT
TO_CHAR(SYSDATE, 'MM'),
TO_CHAR(SYSDATE, 'MON'),
TO_CHAR(SYSDATE, 'MONTH'),
TO_CHAR(SYSDATE, 'RM')
FROM DUAL;
SELECT
TO_CHAR(SYSDATE,'D'),
TO_CHAR(SYSDATE,'DD'),
TO_CHAR(SYSDATE,'DDD')
FROM DUAL;
SELECT
TO_CHAR(SYSDATE, 'DY'),
TO_CHAR(SYSDATE, 'DAY')
FROM DUAL;
SELECT
TO_CHAR(SYSDATE,'YYYY"년" MM"월" DD"일" (DY)')
FROM DUAL;
SELECT EMP_NAME "사원명", TO_CHAR(HIRE_DATE, 'YYYY"년" MM"월" DD"일" (DY)')AS "입사일"
FROM EMPLOYEE;
SELECT EMP_NAME "사원명", TO_CHAR(HIRE_DATE, 'YYYY"년" MM"월" DD"일" (DY)') "입사일"
FROM EMPLOYEE
WHERE EXTRACT(YEAR FROM HIRE_DATE)>=2010
ORDER BY "입사일" ASC;
TO_DATE
* TO_DATE(NUMBER 또는 CHARACTER, '포맷')
* 숫자형 또는 문자형 데이터를 날짜형으로 변환
* 반환값이 DATE형임.
SELECT TO_DATE(20220321)
FROM DUAL;
SELECT TO_DATE('20220321')
FROM DUAL;
SELECT TO_DATE('000101')
FROM DUAL;
SELECT TO_DATE('20100101','YYYYMMDD')
FROM DUAL;
SELECT TO_DATE('041030 143021', 'YYMMDD HH24MISS')
FROM DUAL;
SELECT TO_DATE('140630', 'YYMMDD')
FROM DUAL;
SELECT TO_DATE('980630', 'YYMMDD')
FROM DUAL;
SELECT TO_DATE('140630', 'RRMMDD')
FROM DUAL;
SELECT TO_DATE('980630', 'RRMMDD')
FROM DUAL;
TO_NUMBER
* TO_NUMBER(CHARACTER, '포맷')
* CHARACTER => NUMBER
* => 문자형 데이터를 숫자형으로 반환
* => 반환형은 NUMBER형임
* => 자바의 파싱과 같음
SELECT '123' + '123'
FROM DUAL;
SELECT '10,000,000' + '550,000'
FROM DUAL;
SELECT TO_NUMBER('10,000,000', '999,999,999') + TO_NUMBER('550,000','999,999,999')
FROM DUAL;
SELECT TO_NUMBER('0123')
FROM DUAL;
단일행 함수(NULL처리)
NVL
* NVL(컬럼명, 해당컬럼값이 NULL인경우 반환할 반환값)
* 해당 컬럼값이 존재할 경우(NULL이 아닌경우), 기존의 컬럼값을 반환해줌
* 해당 컬럼값이 존재하지 않을 경우(NULL인 경우), 반환할 값을 지정해주어 반환해줌.
SELECT EMP_NAME, BONUS, NVL(BONUS,0)
FROM EMPLOYEE;
SELECT EMP_NAME, (SALARY+(SALARY*NVL(BONUS,0)))*12
FROM EMPLOYEE;
SELECT EMP_NAME, NVL(DEPT_CODE,'없음')
FROM EMPLOYEE;
NVL2
* NVL2(컬럼명, 결과값1, 결과값2)
* 해당 컬럼값이 존재할 경우(NULL이 아닌 경우), 결과값 1을 반환
* 해당 컬럼값이 존재하지 않는 경우(NULL인 경우), 결과값 2를 반환
SELECT EMP_NAME, BONUS, NVL2(BONUS, '있음', '없음')
FROM EMPLOYEE;
SELECT EMP_NAME, DEPT_CODE, NVL2(DEPT_CODE, '배치완료', '배치미정')
FROM EMPLOYEE;
NULLIF
* NULLIF(비교대상1, 비교대상2)
* 비교대상1이랑 비교대상2가 동일할 경우, NULL을 반환함.
* 값이 동일하지 않을 경우, 비교대상1을 반환
SELECT NULLIF('123','123')
FROM DUAL;
SELECT NULLIF('123','456')
FROM DUAL;
SELECT NULLIF(123,456)
FROM DUAL;
단일행 함수(선택함수)
DECODE
* DECODE(비교대상, 조건값1, 결과값1, 조건값2, 결과값2,...,조건값N, 결과값N, 결과값)
* 비교대상과 조건값을 비교하여, 조건에 부합하면 결과값을 반환함.
* 자바에서 동등비교를 수행하는 SWITCH문과 유사함.
*
* SWITCH(비교대상){
* CASE 조건값1 : 결과값1;
* CASE 조건값2 : 결과값2;
* ...
* CASE 조건값N : 결과값N;
* (DEFAULT : 결과값;) => 생략 가능
* }
SELECT EMP_ID, EMP_NAME, EMP_NO,
DECODE(SUBSTR(EMP_NO,8,1),'1','남자','2','여자','3','남자','4','여자') "성별"
FROM EMPLOYEE;
SELECT EMP_NAME,
JOB_CODE,
SALARY "인상 전",
DECODE(JOB_CODE, 'J7', SALARY+(SALARY*0.1),
'J6', SALARY+(SALARY*0.15),
'J5', SALARY+(SALARY*0.2),
SALARY+(SALARY*0.05)) "인상 후"
FROM EMPLOYEE;
CASE WHEN THEN 구문
* DECODE는 해당조건 검사시 동등비교만을 수행한다면(조건값)
* CASE WHEN THEN구문은 특정조건 제시시 조건식을 기술 가능함.
*
* [표현법]
* CASE WHEN 조건식1 THEN 결과값1
* WHEN 조건식2 THEN 결과값2
* ...
* WHEN 조건식N THEN 결과값N
* ELSE 결과값
* END
SELECT EMP_ID, EMP_NAME,EMP_NO, DECODE(SUBSTR(EMP_NO,8,1),'1','남자',
'2','여자',
'3','남자',
'4','여자') "성별"
FROM EMPLOYEE;
SELECT EMP_ID, EMP_NAME, EMP_NO,
CASE WHEN SUBSTR(EMP_NO,8,1)='1' OR SUBSTR(EMP_NO,8,1)='3' THEN '남자'
ELSE '여자'
END "성별"
FROM EMPLOYEE;
SELECT EMP_NAME, SALARY,
CASE WHEN SALARY > 5000000 THEN '고급'
WHEN SALARY > 3500000 AND SALARY <= 5000000 THEN '중급'
WHEN SALARY <= 3500000 THEN '초급'
END "급여 등급"
FROM EMPLOYEE;