19.11.25. 문자열, 숫자, 날짜 조작 함수
데이터베이스 구현
2019-12-01 23:39:02
함수
function.
크게 single row function 과 multi row function 으로 나눌 수 있다.
-single row function : 단일 행을 기준으로 작업하고, 행당 하나의 결과를 반환한다.
ex) 특정 컬럼의 문자열 길이 : length(ename)
-multi row function : 여러 행을 기준으로, 하나의 결과를 반환.
ex) 그룹 함수 : count, sum, avg
* DUAL TABLE
sys 계정에 있는 테이블로, 누구나 사용 가능하다.
dummy 컬럼 하나만 존재하며 값은 'X' 이며 데이터는 한 행만 존재.
사용 용도 : 데이터와 관련 없이 함수 실행, 시퀀스 실행. merge 문에서, 데이터 복제 시.
▶ CHARACTER
-대소문자 변환
ex) LOWER, UPPER, INITCAP ( 첫 단어만 대문자로.)
--
SLECT LOWER('Hello, World'), UPPER ('Hellp, World'), INITCAP('Hello, World')
FROM dual;
=> 행당 한 번의 함수가 실행된다. 1개의 행이 input --> 1개의 행으로 out put(컬럼)
dual 테이블에는 한 행만 존재하기 때문에 한 행에 한 번씩만 출력된다.
--만일 위를 emp테이블에서 실행시킨다면?
SLECT LOWER('Hello, World'), UPPER ('Hellp, World'), INITCAP('Hello, World')
FROM emp;
=> emp테이블에는 총 14건의 데이터(직원)가 존재. (=14개의 행이 존재.)
따라서 같은 내용이 14행이 출력된다.
-- 컬럼에 function 적용
SELECT empno, LOWER (ename)
FROM emp;
WHERE ename = 'SMITH';
=> select 할 때에만 데이터가 LOWER 함수에 의해 소문자로 보이는 것뿐.
실제 데이터는 변함이 없다. 따라서 위의 쿼리는 조회가 된다.
--where 절에도 사용이 가능.
SELECT empno, LOWER (ename)
FROM emp
WHERE ename = UPPER ('smith')
--아래처럼 좌변을 가공하지 말 것.
SELECT empno, LOWER(ename)
FROM emp
WHERE LOWER(ename) = 'smith';
※위 쿼리에서 where 절에서 ename 이라는 테이블에 함수를 적용했지만, 이 방식은 사용하면 안 된다.
좌변을 가공하면 안 되기 때문. 위위 쿼리처럼 치환시켜서 변수 부분을 가공하는 것이 좋다.
좌변을 가공할 경우 인덱스 활용이 안되기 때문이다.
실제 테이블의 원본을 가공해줘야 결과가 나오는데, 소문자로 만들려면 그 테이블 전체를 읽어야 함.
테이블 컬럼을 가공해도 동일한 결과를 얻을 수 있지만, 테이블 컬럼보다는 상수 쪽을 가공하는 것이
속도면에서 유리하다.
해당 컬럼에 인덱스가 존재하더라도 함수를 적용하게 되면 값이 달라지게 되어
인덱스를 활용할 수 없게 된다.
예외 : FBI(Function Based Index)
(무슨 소린지 모르겠지만 반년 후엔 이해되겠지?)
▶ 문자열 조작 함수
1. CONCAT : 문자열 합침
2. SUBSTR : 문자열에서 일부분을 추출
3. LENGTH : 문자열의 길이
4. INSTR : 문자열에 특정 문자열이 들어있는지 확인. (해당 문자열의 인덱스를 반환한다.)
5. LPAD(RPAD) : 문자열의 왼쪽(오른쪽)에 특정 문자열을 삽입.
설정한 문자열의 길이보다 부족한 만큼 문자열을 채워 넣을 것을 설정해야 함.
6. TRIM : 문자열 앞, 뒤로 공백, 혹은 특정 문자를 제거.
7. REPLACE : 대체.
--1. COCAT 을 사용해보자
SELECT CONCAT (CONCAT ( 'HELLO' , ' , ' ) , 'WORLD' ),
'HELLO' || ' , ' || 'WORLD'
FROM dual;
=> select 절의 윗줄, 아랫줄은 같은 결과를 나타낸다.
하지만, CONCAT 은 2개만 묶을 수 있음에 반해, || 를 사용하면 여러 개를 묶을 수 있다.
--2. SUBSTR
SELECT SUBSTR ('HELLO, WORLD', 1, 5)
FROM dual;
=> (문자열, 시작 인덱스, 종료 인덱스)의 순서로 사용된다.
시작 인덱스는 1부터. 종료 인덱스의 문자열까지 포함한다.
*자바에서는 시작인덱스 0부터, 종료인덱스의 문자열 미포함!!
--4. INSTR
SELECT INSTR ('HELLO, WORLD', 'O')
FROM DUAL;
=> 해당 문자열에 'O' 가 존재하는지 알 수 있다. 존재할 경우, 첫 번째 문자의 인덱스를 리턴한다.
위의 경우 O 가 5번째, 9번째 인덱스에 있지만 5 가 반환됨.
--
SELECT INSTR('HELLO, WORLD', 'O', 6)
FROM DUAL;
=> 문자열의 6번째 인덱스 이후에 등장하는 'O' 문자열의 인덱스 리턴.
--
SELECT INSTR('HELLO, WORLD', 'O', INSTR('HELLO, WORLD', 'O') +1)
FROM DUAL;
=> 괄호 속의 INSTR 은 위위에서 본 것처럼 5를 반환한다. 거기에 +1 을 하면 6.
즉 6번째 인덱스 이후에 등장하는 'O' 를 찾으라는 뜻이므로 위의 결과와 같다.
--5. LPAD(RPAD)
SELECT LPAD ('HELLO, WORLD', 15)
FROM dual;
=> 문자열의 길이를 15로 맞추는데, 부족한 길이는 왼쪽에 L(R)PAD의 디폴트 문자(공백) 으로 채운다.
--
SELECT RPAD ('HELLO, WORLD', 15, '*')
FROM dual;
=> 문자열의 길이를 15로 맞추는데, 부족한 길이는 오른쪽에, '*' 로 채운다.
--6. REPLACE
SELECT REPLACE ('HELLO, WORLD', 'HELLO', 'hello')
FROM dual;
=> 문자열에서 'HELLO' 를 'hello' 로 대체했다.
--7. TRIM
SELECT TRIM(' HELLO, WORLD ') t1
TRIM('H' FROM 'HELLO, WORLD') t2
FROM dept;
=> t1 은 문자열 내의 앞, 뒤의 공백을 제거했다.
t2 는 문자열이 가진 'H'를 제거했다.
dept는 4행을 가진 테이블이므로, 총 4행 실행되었다.
▶
숫자 조작 함수.
1. ROUND : 반올림. ROUND(숫자, 반올림 결과 표시할 소수점 자리)
2. TRUNC : 절삭(=내림). TRUNC(숫자, 절삭할 자리)
3. MOD : 나머지 연산 MOD(피제수, 제수) ex) MOD (5,2) = 1
1. ROUND
SELECT ROUND( 105.54, 1)
FROM dual;
=> 반올림 결과가 소수점 한자리까지 나온다. (소수점 둘째 자리에서 반올림한다.) 결과 : 105.5
--
SELECT ROUND(10.55, 0)
FROM dual;
=> 소수점 첫 번째 자리에서 반올림. 정수로 나온다. 결과 : 11
--
SELECT ROUND(105.54, -1)
FROM dual;
=> 정수 첫번째 자리에서 반올림. 결과 : 110
2. TRUNC
SELECT TRUNC(105.54, 1)
FROM dual;
=> 절삭 결과가 소수점 한자리까지 나온다.
--
SELECT TRUNK(105.55, 0)
FROM dual;
=> 소수점 첫번째 자리에서 절삭. 결과 : 105
--
SELECT TRUNC(105.54, -1)
FROM dual;
=> 정수 첫번째 자리에서 절삭. 결과 : 100
3. MOD
피제수를 제수로 나눈 나머지 값.
MOD(M, 2) 의 결과 종류는 0, 1 이 있다.
0 ~ (제수-1) 개의 결과 종류가 있다.
ex) 3으로 나눌 경우 나머지가 0 혹은 1 혹은 2로, 3개가 올 수 있음.
--
SELECT MOD(142,23)
FROM dual;
=> 결과 : 4
▶ 날짜
DATE : 연월일, 시간, 분, 초
* 도구>환경설정>데이터베이스>NLS : 날짜에 대한 기본 설정을 바꿀 수 있다.
1. SYSDATE
서버의 현재 DATE 를 리턴하는 내장 함수. 특별한 인자가 없다.
2. 날짜 연산 : DATE +/- 정수 = 정수만큼 DATE의 일자를 더하거나 뺀다.
3. 시간 연산 : DATE +/- (정수/24) = 시,분,초 중 시간을 더하거나 뺀다.
DATE +/- (정수/24/60) = 시,분,초 중 분을 더하거나 뺀다.
* 현재 시간 SYSDATE 의 시,분, 초 까지 표현하려면, TO_CHAR 를 통해서
데이터를 변환시켜야 한다.
--
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS')
FROM dual;
-- 2019년 12월 31일을 DATE 형으로 표현하는 방법
SELECT TO_DATE('2019-12-31', 'YYYY-MM-DD')
FROM dual;
4. 형변환
DATE -> CHAR : TO_CHAR(DATE, '포맷')
CAHR -> DATE : TO_DATE(날짜 문자열, '포맷')
5. 포맷
YYYY, MM, DD
D (요일을 숫자로 : 일요일 1, 월요일 2...........토요일 7)
IW(주차 : 1~53) : 1년은 52주 혹은 53주로 구성되어 있다. IW, HH, MI, SS
--정리
SELECT TO_CHAR (SYSDATE, 'YYYY') : 현재 연도.
SELECT TO_CHAR (SYSDATE, 'MM') : 현재 월.
SELECT TO_CHAR (SYSDATE, 'DD') : 현재 일.
SELECT TO_CHAR (SYSDATE, 'D') : 현재 요일.
SELECT TO_CHAR (SYSDATE, 'IW') : 현재 주차. (해당 주의 목요일을 주차의 기준으로 잡는다.)
--2019년 12월 31일은 몇 주 차가 나오는가?
SELECT TO_CHAR (TO_DATE(2019-12-31', 'YYYY-MM-DD'), 'IW')
FROM dual;
=> 결과 : 1 ∵ 이 주의 목요일이 2020년 1월의 첫째 주이기 때문.
▶ 날짜 조작 함수
1. MONTH_BETWEEN ( DATE1, DATE2) : DATE 1과 DATE 2 사이의 개월 수.
2. ADD_MONTHS (DATE, 가감할 개월 수) : DATE에서 특정 개월 수를 더하거나 뺀 날짜.
3. NEXT_DAY (DATE, WEEKDAY(1~7)) : DATE 이후 첫 번째 위클리 날짜.
4. LAST_DAY (DATE) : DATE 가 속한 월의 마지막 날짜.
*바인드 변수 : PARAM
툴마다 방식이 다르지만, 오라클 sql 에서는 :yyyymm 으로 하면 된다.
--
SELECT :YYYYMM PARAM, TO_CHAR(LAST_DAY(TO_DATE(:YYYYMM,'YYYYMM')), 'DD')
FROM dual;
=> 사용자에게 입력받은 달의 마지막 날짜 'dd'(일) 를 출력한다.
'database' 카테고리의 다른 글
oracle - CONDITION, VIRTUAL BOX 설치 (0) | 2023.03.13 |
---|---|
oracle - 형변환의 종류, 숫자포맷, NULL처리 함수 (0) | 2023.03.13 |
oracle - 연산자 우선순위, ORDER BY, ROWNUM (0) | 2023.03.13 |
oracle - IN, LIKE, IS NOT NULL, AND, OR, NOT (0) | 2023.03.13 |
oracle 컬럼조회(WHERE, TO-DATE, ALIAS, UPDATE 등) (0) | 2023.03.13 |