Function
함수
데이터 형식
오라클은 표준 SQL + 종속 SQL을 함께 사용, 표현 방법이 조금씩 다르다. 기본 oracle 데이터 형식은 31개 정도가 있다. 그 중 주로 사용하는 데이터 형식은 다음과 같다.
문자 VARCHAR2 |
VARCHAR2 / CHR : 영문 -1바이트, 한글 -3바이트 CHAR(50) : ‘abc’ [abc+47바이트 고정] VARCHAR2(50): ‘abc’ [abc] /최대 50바이트란 의미 NCHAR/ NVARCHAR2/CLOB : 유니코드 2바이트 한글 ’ ‘: 대소문자 구분 |
---|---|
정수 NUMBER(8) |
BINARY_INT INT NUMBER(8) NUMBER(8, 0) |
실수 NUMBER(8, 2) |
BINAR_FLOAT FLOAT NUMBER(8, 2) 정수는 6 소수2 이하만 표현하겠다. |
날짜 DATE |
DATE: 초 단위까지 표현 TIMESTAMP: 1/1000초까지 표현 |
대용량 | CLOB(1TB 문자열 대용량 데이터) BLOB(1TB 바이너리(2진 파일ex.사진,동영상) 대용량 데이터) BFILE / BIN |
SQL 기호 정리
$ | $기호 |
---|---|
L | LOCALE CURRENCY - ₩ |
9 | 한 자리 숫자 |
0 | 한 자리 숫자 |
, | , 기호 |
YY - 2000년대 YYYY RR(0-49, 50-99) |
년도 |
MM | 월 |
DD | 일 |
HH HH24 |
시간 |
MI | 분 |
SS | 초 |
---|---|
DAY | 요일 |
- DUAL 테이블
-
가상 임시 테이블. 특정 함수의 결과를 조회할 때 사용하는 테이블. 1행만 존재한다.
함수
함수정리표
함수 중에 변수가 없는 몇 개의 함수들이 있다.
타입변환함수 | CAST TO_DATE TO_CHAR TO_NUMBER |
---|---|
그룹함수 | SUM AVG MIN MAX COUNT STDEV VARIANCE |
문자데이터함수 | UPPER LOWER INITCAP LENGTH LENGTHB SUBSTR INSTR LTRIM RTRIM |
숫자데이터함수 | MOD: 나머지 함수 ex. MOD(10,3) > 1 ROUND: 반올림 함수 ex. ROUND(10/3, 0) > 3 정수형태 표현 ROUND(3.6789, 1)> 3.7 소수점 첫자리까지 ROUND(336.6789, -1) > 340 10자리까지 TRUNC: 반올림 하지 않고 버림 TRUNC(3.6789, 1)> 3.6 |
날짜데이터함수 | SYSDATE SYSTIMESTAMP - 1/1000 초까지 표현 ADD_MONTHS() - 월을 더하는 것 SELECT ADD_MONTHS(SYSDATE,1)FROM DUAL; (30일을 더하면 정확한 월 계산이 되지 않음) MONTHS_BETWEEN(): 월과 월 사이의 값을 구해준다. |
순위함수 | ROWNUM (subquery 필수) ROW_NUMBER() RANK() DENSE_RANK() 사용: 순위를 정하는 함수() OVER (PARTITION BY 순위를 만들어야 할 소그룹컬럼명 ORDER BY ??) |
NULL처리함수 | NVL() ex. NVL(salary, 0) // salary가 null인 사람은 공백이 아닌 0으로 표현 |
기타 | INSTR: 포함되어있는가 INSTR(‘This is Java’, ‘Java’) = 0 : 포함하고 있지 않다 INSTR(‘This is Java’, ‘Java’) > 0 : 포함하고 있다. |
문자열 결합은 concat 또는 || |
함수의 사용과 설명
T0_CHAR TO_NUMBER **TO_DATE
SELECT 100+200 FROM DUAL;
SELECT '100'+'200' FROM DUAL; > 0-9구성, 자동 숫자변환 300 출력
- ‘100’ 은 ‘ ‘ 안에 있어도 자동으로 숫자 변환이 가능하다. 그러나 ‘123, 456’의 식은 숫자 변환 X
TO_NUMBER
문자열 타입을 숫자 타입으로 변환할 때
사용 예시
예1) ‘123, 456’ (문자)를 숫자로 변환
TO_NUMBER('123,456', '999,999');
: 9는 숫자 한 자리, 구분자(,)를 빼고 숫자로 인식
SELECT TO_NUMBER('123,456', '999,999')+'200' FROM DUAL;
TO_NUMBER('$100', '$999'); > 정수 100으로 변환
SELECT TO_NUMBER('$100', '$999')+ TO_NUMBER('$200', '$999') FROM DUAL;
: 9라는 것은 숫자로 인식, 나머지는 '기호'로 인식, 버린다.
TO_CHAR
숫자타입을 문자열타입으로 변환할 때
예1)
SELECT 123456 FROM DUAL; -> $123,456으로 출력하겠다.
TO_CHAR(123456, '$999,999')
SELECT TO_CHAR(123456, '$999,999') FROM DUAL;
SELECT TO_CHAR(123456.789, '$999,999') FROM DUAL;
:소수점부분이 잘렸을 경우, 표현 가능(반올림). 그러나 정수부분이 초과되면 오류
SELECT TO_CHAR(123456.789, '$999,999.99') FROM DUAL;
:소수점까지 표현
- 소수점이 잘렸을 때 반올림으로 표현가능, 그러나 정수부분이 초과되면 오류!
예2)
SELECT TO_CHAR(123456, ‘L999,999’) FROM DUAL; > L은 원화로 표시
TO_DATE
- 현재 오라클에서 설정된 날짜의 형태 조회하기
SELECT * FROM DICT; : 딕셔너리 테이블 이름들이 나옴
SELECT table_name FROM dict WHERE table_name LIKE '%NLS%': 이 안에 포멧이 있음
SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT';
: 날짜 포멧 조회의 최종문
-
날짜 데이터를 문자열 데이터로
TO_CHAR(SYSDATE, ‘YYYY/MM/DD DAY HH:MI:SS’)
SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD DAY HH24:MI:SS') FROM DUAL;
분리기준이 특수기호가 아닐 때: “ “ 이중 따옴표 안에 분리자를 넣어준다.
SELECT TO_CHAR(SYSDATE, 'YYYY" YEAR" MM" MONTH" DD"DAY" HH"HOUR"MI" MIN"SS" SEC"') FROM DUAL;
불필요한 것을 생략할 때: fm
SELECT TO_CHAR(SYSDATE, fm'YYYY" YEAR" MM" MONTH" DD"DAY" HH"HOUR"MI" MIN"SS" SEC"') FROM DUAL;
:불필요한 부분 앞에 fm을 넣어주면 그 부분에서 필요한 값만 조회된다.
연산자 사용
select sysdate + 1 from dual; : 다음 날짜가 조회
select '25-MAR-21' + 1 from dual; : 오류! '25-MAR-21'값은 sysdate값을 드러내지 않는다.
- 문자데이터를 날짜데이터로
select to_date('25-MAR-21', 'yy/mm/dd') + 1 from dual;
1년 뒤의 날짜 조회하기
select sysdate + 365 from dual;
select to_char(sysdate, 'yyyy') + 1 from dual;
:문자열 타입으로 원하는 날짜부분(연도)를 변환 뒤 연산자를 사용하면 된다.
예시) 05년도 입사자 조회하기
select hire_date from employees where to_char(hire_date, 'yy') = '05';
INSTR
INSTAR(‘This is JAVA’, ‘JAVA’) : ‘This is JAVA’에 ‘JAVA’가 포함되어 있는가
select first_name from employees where INSTR(first_name, 'er')= 0;
: 포함하고 있지 않다.
select first_name from employees where INSTR(first_name, 'er') > 0;
: 포함하고 있다. 0이면 없다는 의미
select hire_date from employees where instr( hire_date, 'MAR') = 4;
:hire_date의 4번째 자리에 MAR이 있는가
- 연산자 = > 를 사용하여 존재여부를 따진다.
대소문자변환 LOWER UPPER INITCAP
가령 어떤 키워드를 조회할 때, 그 문자가 어떤 식의 형태를 갖고 있는지 알 수 없을 경우 사용
where lower(first_name) = 'jennifer'
where upper(first_name) = 'JENNIFER'
where initcap(first_name) = initcap('JENNIFER')
:initcap은 문자의 원래 값을 조회한다.
- = 연산자로 조회시 각 변환타입이 대조 데이터와 맞는지(둘 다 소문자인지, 대문자인지)확인.
REPLACE
REPLACE/TRANSLATE('THIS IS JAVA', 'JAVA', 'ORACLE')
- SUBSTR
-
문자열 함수, 숫자나 날짜 - to_char - 문자열 / 숫자나 날짜는 문자열로 자동형변환 가능
SUBSTR(‘this is Java’, 1, 2) ==>th
: 위치를 주면 데이터를 리턴(1자리부터 2까지 리턴)
INSTAR
INSTR(‘this is Java’, ‘this’) ==> 1
: 데이터를 주면 위치를 리턴
LTRIM/RTRIM
select ltrim(' aaa ') from dual; : 'aaa '
select rtrim(' aaa ') from dual; : ' aaa'
의미 없는 공백을 없앨 때:
select rtrim('##aa###', '#') from dual; : 'aa###'
ROUND / TRUNC
ROUND: 반올림 함수 TRUNC: 반올림 하지 않고 버림
ROUND(10/3, 0) : 3
ROUND(3.6789, 1) : 3.7(소수점 첫자리, 반올림)
ROUND(336.6789, -1) : 340, 10자리까지 -2는 100자리까지
TRUNC(3.6789, 1) : 3.6
입사연도별 급여 평균 조회하되 평균이 정수로 보이도록:
select substr(hire_date, 4, 3), trunc(avg(salary), 0) from employees group by substr(hire_date, 4, 3);
입사 경과년수 조회:
select round((sysdate-hire_date)/365) from employees;
MOD
:나누고 나머지를 출력하는 함수
employees table에서 홀수 사번 조회:
select employee_id from employees where mod(employee_id, 2) = 1;
순위함수 ROW RANK() DENSE_RANK()
ROW / RANK() / DENSE_RANK() OVER (PARTITION BY ORDER BY ) FROM__;
-
- ROW_NUMBER
-
같은 순위를 동일한 순위로 처리하지 않음
SELECT first_name as NAME, salary as SALARY, ROW_NUMBER() OVER (ORDER BY salary DESC) employees; NAME SALARY RANK -------------------- ---------- ---------- Steven 24000 1 Neena 17000 2 Lex 17000 3 John 14000 4 Karen 13500 5 Michael 13000 6 Nancy 12008 7 Shelley 12008 8 Alberto 12000 9 Lisa 11500 10 Den 11000 11
- RANK() OVER
: 동일 값을 동일 순위로 매겨주는데 중복된 순서는 + 해서 다음 순위에 매겨줌
SELECT first_name as NAME, salary as SALARY, RANK() OVER (ORDER BY salary DESC) AS RANK FROM employees;
NAME SALARY RANK
-------------------- ---------- ----------
Steven 24000 1
Neena 17000 2
Lex 17000 2
John 14000 4
Karen 13500 5
Michael 13000 6
Nancy 12008 7
Shelley 12008 7
Alberto 12000 9
Lisa 11500 10
Den 11000 11
-
- DENSE_RANK()
-
동일 값을 동일 순위로 매겨주고 중복된 순위를 +해서 다음 순위에 매기지 않음.
SELECT first_name as NAME, salary as SALARY, DENSE_RANK() OVER (ORDER BY salary DESC) AS RANK FROM employees; NAME SALARY RANK -------------------- ---------- ---------- Steven 24000 1 Neena 17000 2 Lex 17000 2 John 14000 3 Karen 13500 4 Michael 13000 5 Nancy 12008 6 Shelley 12008 6 Alberto 12000 7 Lisa 11500 8 Den 11000 9
-
- PARTITION BY (파트별로 조회할 때)
SELECT first_name as NAME, salary as SALARY, DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS RANK FROM employees; NAME SALARY RANK -------------------- ---------- ---------- Jennifer 4400 1 Michael 13000 1 Pat 6000 2 Den 11000 1 Alexander 3100 2 Shelli 2900 3 Sigal 2800 4 Guy 2600 5 Karen 2500 6 Susan 6500 1 Adam 8200 1 NAME SALARY RANK -------------------- ---------- ---------- Matthew 8000 2 Payam 7900 3 Shanta 6500 4 Kevin 5800 5 Nandita 4200 6 Alexis 4100 7 Sarah 4000 8 Britney 3900 9 Kelly 3800 10 Jennifer 3600 11 Renske 3600 11 . .
NULL
NULL값을 공백 대신 다른 값으로 변환. (그 값이랑 타입이 같아야 한다)
커미션을 받지 못 하는 사원들 null 을 0으로 조회:
select first_name, NVL(commission_pct, 0) from employees;
select first_name, NVL(to_char(commission_pct), 'NO BONUS') from employees;
: null값과 타입이 같지 않을 경우, 대신한 값으로 타입변환을 해준다