SQL 함수 (FUNCTION)
자바의 메소드와 비슷한 역할
전달된 값들을 읽은 후, 메서드에 맞는 계산결과를 반환
1) 단일행함수: n개의 값을 읽어서 n개의 값 리턴
2) 그룹함수: n개의 값을 읽어서 1개의 값 리턴
==> 단일행 함수와 그룹함수는 반환결과의 행수가 다르므로
일반적으로 하나의 쿼리문에 함께 사용할 수 없음!
단일행 함수
1. 문자열 관련 함수 (단일)
1) LENGTH / LENGTHB
- LENGTH (STR) : 전달된 STR의 글자수를 컬럼으로반환 (반환타입: NUMBER)
- LENGTHB (STR): 전달된 STR의 바이트 수를 컬럼으로 반환 (반환타입: NUMBER)
-> 숫자, 영문, 특문(!, ~) : 한글자당 1BYTE
-> 한글 ('ㄱ', 'ㅏ', '강'): 한글자당 3BYTE
SELECT LENGTH('ORACLE'), LENGTHB('ORACLE') -- 알파벳은 하나당 1BYTE로 인식
FROM DUAL;
SELECT LENGTH('오라클'), LENGTHB('오라클') -- 한글은 하나당 3BYTE 로 인식
FROM DUAL;
SELECT EMAIL, LENGTH(EMAIL), LENGTHB(EMAIL), EMP_NAME, LENGTH(EMP_NAME),LENGTHB(EMP_NAME)
FROM EMPLOYEE;
2) INSTR
- INSTR(STR) : 문자열로부터 특정 문자의 위치값을 반환 (반환타입: NUMBER)
INSTR(STR, STR내 '특정문자', POSITION, 순번 (몇번째 '특정문자'를 찾을건지 )
* POSITION : 시작위치
찾을 위치의 시작값, 순번은 생략가능 (생략시 STR 가장 앞부터 탐색)
SELECT INSTR('IWANTOGOHOMEEARLYTODAY', 'A')
FROM DUAL;
-- 찾을위치 생략시 기본적으로 가장 앞에서부터 첫번째 글자 탐색
SELECT INSTR('IWANTOGOHOMEEARLYTODAY', 'A', -1, 2)
FROM DUAL;
------맨 뒤부터 'A'를 찾을건데, 2번째로 찾은 'A'가 문자열 앞에서부터 몇번째에 있는지
SELECT EMP_NAME AS "사원명", INSTR(EMAIL, '@') "@의 위치는?"
FROM EMPLOYEE;
3) SUBSTR
- 문자열로부터 특정 문자열 추출하여 반환 (반환타입: CHARACTER)
- SUBSTR (STR, POSITION, LENGTH)
- STR: 내가 추출하고 싶은 문자열 혹은 문자타입컬럼
- POSITION: 시작위치
- LENGTH: 추출한 문자개수, 생략시 끝까지
SELECT SUBSTR('IWANTTOGOHOMEANDSLEEPEARLY', 6, 4) -- 위치 인덱스는 1부터 시작
FROM DUAL;
SELECT SUBSTR('IWANTOGOHOMEEARLY', -5, 3) -- 뒤에서 5번째부터 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) = '1';
----여자사원만 조회(사원명, 급여)------------------
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) IN ('2', '4');
---이메일에서 아이디부분만 추출해서 조회---이름, 이메일 아이디
--EMAIL컬럼의 값에서 @ 앞까지
-- EMAIL컬럼에서 @위치를 INSTR을 통해 반환받은 후
--SUBSTR을 통해 1부터 @위치-1까지 반환받기
SELECT EMP_NAME, EMAIL, SUBSTR ( EMAIL, 1, INSTR(EMAIL, '@')-1)
FROM EMPLOYEE;
4) LPAD /RPAD
LPAD: 문자열 왼쪽채우기
RPAD: 문자열 오른쪽 채우기
- LPAD /RPAD (STR, 최종 반환문자의 길이, 덧붙일 문자) : (CHARACTER 반환)
* 덧붙이는 문자는 생략 가능
SELECT RPAD('121212-2', 14, '*')
FROM DUAL;
-- 121212-2******
--기입한 문자열을 14자리로 채운 후 반환
-- (14자리에 입력한 문자를 앞부터 기입 후, 남는 뒷쪽칸에는 *를 채워 반환)
--모든 직원의 주민번호 뒤 6자리를 마스킹하여 표현, 이름, 주민번호
SELECT EMP_NAME, RPAD(SUBSTR(EMP_NO, 1, 8), 14, '*')
FROM EMPLOYEE;
5) LOWER / UPPER /INITCAP
- LOWER(STR) : 문자열을 전부 소문자로 변환
- UPPER(STR) : 문자열을 전부 대문자로 변환
- INITCAP(STR): 각 문자열 가장 앞문자만 대문자로 변환
SELECT LOWER ('WELCOME TO ORACLE') -- welcome to oracle
FROM DUAL;
SELECT UPPER ('welCome to oRacle') --WELCOME TO ORACLE
FROM DUAL;
SELECT INITCAP('welcome to oracle') -- Welcome to orcle
FROM DUAL;
6) CONCAT
- CONCAT(STR1, STR2) : 전달받은 문자열과 문자열을 하나로 연결하여 반환 (반환값 : CHARACTER)
- 연결연산자와( ||) 의 차이: 최대 2개 문자열만 연결 가능, 3개이상 불가!!
SELECT CONCAT('가나다' , 'ABC')
FROM DUAL; -- 가나다ABC
7) REPLACE
- REPLACE (STR, '찾을문자', '바꿀문자') : (반환값: CHARACTER)
- STR 내의 '찾을 문자'를 '바꿀문자'로 변환 후 반환
SELECT REPLACE('오늘은 정말이지 피곤한 하루예요','피곤', '행복')
FROM DUAL; -- 오늘은 정말이지 행복한 하루예요
8) TRIM
- TRIM ( '지우고싶은 문자열' FROM '기존 문자열') : (반환값: CHARACTER)
- TRIM ( LEADING STR2 FROM STR1)
- TRIM ( TRAILING STR2 FROM STR1)
- TRIM ( BOTH STR2 FROM STR1)
- LEADING(앞쪽) / TRAILING(뒤쪽) / BOTH(앞뒤 : DEFAULT)
: 문자열 앞, 뒤, 앞뒤에 붙은 특정 문자를 제거한 나머지 문자열을 반환
SELECT TRIM('ㅋ'FROM'ㅋㅋㅋㅋㅋㅎ ㅏ피곤하다 ㅋㅋㅋ')
FROM DUAL; -- 기본값 BOTH, 앞뒤값 제거, ㅎ ㅏ피곤하다
SELECT TRIM(LEADING'ㅋ'FROM'ㅋㅋㅋㅋㅋㅎ ㅏ피곤하다 ㅋㅋㅋ')
FROM DUAL; -- 앞쪽 LEADING, 앞쪽값 제거, ㅎ ㅏ피곤하다 ㅋㅋㅋ
SELECT TRIM(TRAILING'ㅋ'FROM'ㅋㅋㅋㅋㅋㅎ ㅏ피곤하다 ㅋㅋㅋ')
FROM DUAL; --뒤쪽 TRAILING, 뒤쪽값 제거, ㅋㅋㅋㅋㅋㅎ ㅏ피곤하다
2. 숫자 관련 함수
1) ABS (NUMBER) 절대값
SELECT ABS(-10) AS "절댓값"
FROM DUAL;
2) MOD (나머지, 일반연산자로 못구함)
- MOD(NUM1, NUM2): 두 수를 나눈 나머지값 반환
SELECT MOD(10, 3)
FROM DUAL;
3)ROUND
- ROUND (NUMBER, n) : 반올림,
- 소수점 아래 n번째 수에서 반올림 (생략가능 / DEFAULT : 0 )
SELECT ROUND(123.4567, 3) -- 123.457
FROM DUAL;
4) CEIL
- CEIL(NUMBER) : 올림
- 소수점 첫 번째 자리에서 무조건 올림, 정수반환
SELECT CEIL(123.1565) -- 124
FROM DUAL;
5) FLOOR
- FLOOR (NUMBER) : 올림
- 소수점 첫 번째 자리에서 무조건 버림, 정수반환
SELECT FLOOR (123.156) ---123
FROM DUAL;
-------------사원, 사원의 근무일수 반환--------
SELECT EMP_NAME, CONCAT(FLOOR(SYSDATE - HIRE_DATE), '일') AS "근무일수" ---- SYSDATE는 소숫점이 더럽게 나오니 요러케 처리하면 됨
FROM EMPLOYEE;
3. 형변환 함수
1 ) TO_CHAR
- 숫자형, 날짜형 데이터를 문자형타입으로 변환(반환값: CHARACTER)
- NUMBER / DATE => CHARACTER
[표현법]
SELECT TO_CHAR (NUM/DATE , 변환할 형태지정)
SELECT TO_CHAR(SYSDATE) AS 문자열타입
FROM DUAL;
SELECT TO_CHAR (YYYY-MM-DD) AS 문자열타입
FROM DUAL;
SELECT TO_CHAR(1234, '00000') --- 앞내용을 뒷내용에 넣되 앞쪽빈칸에 0을 채우겠다
FROM DUAL;
SELECT TO_CHAR(1234,'99999')
FROM DUAL; -- 빈칸에 공백을 채워넣겠다, 그러면 9는 어떻게채워?
SELECT TO_CHAR(1234, 'L00000') -- L: 통화표시
FROM DUAL;
SELECT TO_CHAR(1234, 'L99,999') -- L: 통화표시
-- 숫자가 문자로 바뀌면서 자릿수를 넣어줄 수 있음
FROM DUAL;
SELECT EMP_NAME, TO_CHAR(SALARY, 'L999,999,999') "급여"
FROM EMPLOYEE; ---- 완전 편하다...
2) NULL 처리 함수 (NVL) **중요
해당 컬럼의 값이 NULL일 경우 , NULL 대신 지정한 값을 결과로 반환
1 > NVL(컬럼명, NULL을 대신할 지정값)
2 > NVL2 (컬럼명, NULL이 아닌 값 대신 넣을 내용, NULL일시 넣을 내용)
연산시, NULL이 있으면 NULL을 만나는 결과들은 다 NULL로 반환되는 현상을 막기 위해
NULL이 나올 수 있는 부분을 NVL로 감싸서 NULL이 아닌 지정한 값을 반환하도록 만든다
SELECT EMP_NAME, BONUS, (SALARY +(SALARY* NVL(BONUS, 0) ))*12
FROM EMPLOYEE;
"보너스 포함 연봉"
----NULL로 인해 문제가 발생하는 BONUS를 다른 값으로 감싸줌
--- BONUS를 받지 못해 NULL이 들어있는 값들을 0으로 대체하여 연산
----완전 편하다..
SELECT EMP_NAME, NVL(DEPT_CODE, '부서없음')
FROM EMPLOYEE;
----NULL 대신 '부서없음' 이 반환됨
SELECT EMP_NAME, NVL2(DEPT_CODE, '부서있음', '부서없음')
FROM EMPLOYEE;
4. 선택함수
1) DECODE
- 자바에서의 SWITCH문과 유사
- DECODE ( 비교대상(컬럼명, 산술연산, 함수), 조건값, 결과값)
--사원명이랑 주민등록번호로부터 성별자리 추출하여 1,2로 보여준 것
SELECT EMP_NAME, SUBSTR(EMP_NO, 8, 1)
FROM EMPLOYEE;
SELECT EMP_NAME, DECODE ( SUBSTR(EMP_NO, 8, 1) , 1, '남', 2, '여') AS "성별"
FROM EMPLOYEE;
--직원들의 급여를 인상시켜 조회
--직급코드가 'J7'인 사원은 급여 10% 인상하여 조회
--직급코드가 'J8'인 사원은 급여 15% 인상하여 조회
--직급코드가 'J5'인 사원은 급여 20% 인상하여 조회
-- 사원명, 직급코드, 급여, 인상 후 급여
-- EMPLOYEE 테이블에서
SELECT EMP_NAME
, JOB_CODE
, SALARY
AS "인상 전 급여"
, DECODE ( JOB_CODE,
'J5',SALARY*1.2 ,
'J8', SALARY*1.1 ,
'J7', SALARY*1.2 )
AS "인상 후 급여"
FROM EMPLOYEE;
2) CASE - WHEN - THEN 구문
-자바의 IF - IF ELSE
[표현법]
CASE WHEN 조건식 1 THEN 결과값 1
WHEN 조건식 2 THEN 결과값 2
...
ELSE 결과값
END
*/
SELECT
EMP_NAME
, DECODE (
SUBSTR(EMP_NO, 8, 1), 1, '남', 2, '여') AS "성별"
FROM EMPLOYEE;
-----CASE WHEN THEN
SELECT EMP_NAME,
CASE
WHEN SUBSTR(EMP_NO, 8 , 1) = '1' THEN '남'
ELSE '여'
END
FROM EMPLOYEE;
-----사원명, 급여, 급여등급
SELECT*
FROM EMPLOYEE;
-- 사원명, 급여, 급여등급 (초급, 중급, 고급)
-- SALARY값이 500만원 초과일 경우 '고급'
-- SALARY값이 500만원 이하 350만원 초과일 경우'중급'
-- 350만원 이 하일 경우 '초급'
SELECT EMP_NAME, SALARY,
CASE
WHEN SALARY > 5000000 THEN '고급'
WHEN SALARY > 3500000 AND SALARY <= 5000000 THEN'중급'
ELSE '초급'
END
FROM EMPLOYEE;
'Database' 카테고리의 다른 글
[SQL] 집합연산자 (SET OPERATOR) (0) | 2022.10.04 |
---|---|
[SQL] 조인 (JOIN) (1) | 2022.10.04 |
[SQL] 함수 - 그룹함수 (0) | 2022.10.04 |
[SQL] DML - SELECT문 (0) | 2022.10.04 |
[SQL] 명령어의 구분 (DML / DDL/ DCL/TCL) (0) | 2022.10.04 |