Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

노력하는문돌이

3. 데이터 가공 함수(문자, 숫자, 날짜 등) 본문

프로그래밍 언어 공부/SQL

3. 데이터 가공 함수(문자, 숫자, 날짜 등)

성균관_해태 2021. 10. 15. 17:39

 

1. 문자 데이터 가공 함수

1-1. 대 ˙ 소문자를 바꿔 주는 UPPER, LOWER, INITCAP 함수

함수 설명
UPPER 괄호 안 문자 데이터를 모두 대문자로 변환
LOWER 괄호 안 문자 데이터를 모두 소문자로 변환
INITCAP 괄호 안 문자 데이터 중 첫 글자는 대문자로, 나머지는 소문자로 변환
  • UPPER / LOWER / INITCAP 함수는 모두 함수 안에 열(데이터)를 넣는 형태로 수행 가능
## 기본 형태
SELECT UPPER(열1), LOWER(열2), INITCAP(열3) FROM TABLE;

## 활용 형태
SELECT * FROM TABLE
WHERE UPPER(열1) == UPPER('Like'); ## 대소문자를 하나로 통일해서 반환

## LIKE와의 활용 형태
SELECT * FROM TABLE
WHERE UPPER(열1) LIKE UPPER('%scott%');

1-2. 문자열 길이를 구하는 LENGTH 함수

  • Python에서의 len() 함수와 동일하게, character의 길이를 반환하는 함수
  • 글자 개수가 아닌, 바이트 크기를 구하려면 LENGTHB를 사용하면 된다.
SELECT ENAME, LENGTH(ENAME) FROM EMP;

1-3. 문자열 일부를 추출하는 SUBSTR 함수

  • R에서의 SUBSTRING 함수와 동일한 작업을 수행하는 함수
  • SUBSTRING( data, i, n)으로 i번째부터 n만큼 뽑는 함수라고 생각하면 된다. (n이 없으면 전체 반환)
## 활용 예시

SELECT JOB, SUBSTR(JOB,1,2), SUBSTR(JOB,3,2) FROM EMP;
##JOB 열의 1번째부터 2개
##JOB 열의 3번째부터 2개

## length와의 활용 예시

SELECT JOB, SUBSTR(JOB, -LENGTH(JOB)) FROM EMP; ## 뒤에서부터 -LENGTH만큼 출력
## 파이썬에서의 -로 INDEX 반환하는 것과 동일한 이치

1-4. 문자열 데이터 안에서 특정 문자 위치를 찾는 INSTR함수

  • INSTR([데이터],[타겟 문자],[시작 위치],[몇 번째 문자?])
  • 위의 파라미터를 통해서 주어진 데이터에서 몇 번째부터 원하는 문자의 INDEX를 반환 받을지 작성
  • 마지막 파라미터를 통해, K번째 원하는 문자를 반환받을 수 있음
SELECT INSTR('HELLO ORACLE!','L') AS INSTR_1 ## 첫 번째 L INDEX 반환
	   INSTR('HELLO ORACLE','L',5) AS INSTR_2 ## 5번째 L INDEX 반환
       INSTR('HELLO ORACLE','L',2,2) AS INSTR_3 ## INDEX 2번부터 시작해서 5번째 L INDEX반환​

 

1-5. 특정 문자를 바꾸는 REPLACE

  • 파이썬와 R에서 나오는 REPLACE와 동일한 메커니즘의 함수
  • REPLACE([DATA],[TARGET],[RESULT])의 형식으로 TARGETㅇ르 RESULT로 바꾸는 작업을 수행한다  
  • SELECT '010-1234-5678' AS REPLACE, REPLAEC('010-1234-5678','-','') AS REPLACE2 FROM TABLE2;​

1-6. 데이터의 빈 공간을 문자로 채우는 LPAD, RPAD

  • 패딩이라는 말처럼, 왼쪽 및 오른쪽에 대해 원하는 자리수만큼 특정 문자열을 반복하는 것을 말한다
  • LPAD([데이터],[문자열 길이],[어떤 문자로?])의 형태로 사용하면 된다. (어떤 문자의 default는 공백)
SELECT LPAD('abc',5,'_') AS LPAD1 ## 이럴 경우 __abc가 된다.
RPAD('ABC',5,'_') AS RPAD1 ## 이럴 경우 ABC__가 된다.

1-7. 두 문자를 합치는 CONCAT 함수

  • EXCEL에서의 CONCAT와 동일한 작업을 수행하는 함수
  • CONCAT([문자1], [문자2]) 이런식으로 표현할 수 있음
  • CONCAT 대신에 ' || ' 연산자도 활용할 수 있음
  • 열1 || 열2 OR 열1 || " : " || 열2 이런식으로 표현 가능
SELECT CONCAT(열1,열2),
		CONCAT(열1, CONCAT(" : ",열2))
        FROM TABLE;

1-8. 특정 문자를 지우는 TRIM, LTRIM, RTRIM 함수

  • 문자를 제거하는 함수이며 기본적으로 TRIM([삭제하고 싶은 문자] FROM [문자열])로 이해하면 된다.
  • DEFAULT로 공백을 제거함, LTRIM은 좌측을, RTRIM을 우측부터 하나만 제거하는 함수라고 생각
SELECT TRIM('  ORACLE  ') AS TRIM, ## 이렇게 DEFAULT값을 이용할 수 도
		TRIM(BOTH '_' FROM '__ORACLE__') AS TRIM ## 이렇게 표현할 수도 
        FROM TABLE;

2. 숫자 데이터 및 자료형 변환 관련 함수

2-1. 숫자데이터 관련 요약

  • 파이썬에서 활용하는 함수들과 동일한 이름 및 과정을 수행
함수 설명 형태 비고
ROUND 지정된 숫자의 특정 위치에서 반올림한 값을 반환 ROUOND(숫자, 위치) 위치가 음수면 10의 자리
TRUNC 지정된 숫자의 특정위치에서 버림한 값을 반환 TRUNC(숫자,위치) 위치가 음수면 10의 자리
CEIL 지정된 숫자보다 큰 정수 중 가장 작은 정수를 반환 CEIL(숫자)  
FLOOR 지정된 숫자보다 작은 정수 중 큰 정수를 반환 FLOOR(숫자)  
MOD 지정된 숫자를 나눈 나머지 값을 반환 MOD(숫자, 나눌 숫자)  
## ROUND
SELECT ROUND(1234.5678) AS ROUND, ## 이렇게 하면 1235
		ROUND(1234.5678,0), ## 1235
        ROUND(1234.5678,1), ## 1234.6
        ROUND(1234.5678,-1) ## 1230
        FROM TABLE;
        
## TRUNC
SELECT TRUNC(1234.5678) AS TRUNC FROM DUAL

## CEIL / FLOOR
SELECT CEIL(3.14), FLOOR(3.14) FROM DUAL;

## MOD
SELECT MOD(10,3), MOD(2,1) FROM DUAL;

2-2. 날짜 데이터를 다루는 날짜 함수

  • 날짜 데이터는 숫자 데이터와 함께 연산이 가능하다. (날짜 ± 숫자)는 날짜에서 숫자만큼 더하고 뺀 날짜를, 날짜-날짜는 두 날짜 간의 차이를 의미
  • 단, 날짜 데이터 + 날짜 데이터는 연산이 불가능하다. 
함수명 기능 형태
SYSDATE 현재 날짜와 시간 출력 SYSDATE
ADD_MONTHS N개월 후를 출력 ADD_MONTHS([날짜], [숫자]
MONTHS_BETWEEN 두 날짜 간의 개월 차이 출력 MONTHS_BETWEEN(A,B)
NEXT_DAY 돌아오는 요일의 날짜를 출력 NEXT_DAY(날짜, 요일 문자)
LAST_DAY 해당 날짜가 속한 달의 마지막 날짜 출력 LAST_DAY(날짜)
ROUND 날짜 데이터를 형식에 맞게 출력 ROUND(날짜, 포맷)
TRUNC 날짜 데이터를 형식에 맞게 출력 TRUNC(날짜, 포맷)
SELECT SYSDATE,
	ADD_MONTHS(SYSDATE,3),
    MONTHS_BETWEEN(SYSDATE, HIREDATE),
    NEXT_DAY(SYSDATE,'월요일'),
    LAST_DAY(SYSDATE),
    ROUND(SYSDATE,'HH'),
    TRUNC(SYSDATE,'HH') FROM TABLE;

2-3. 날짜, 숫자 데이터를 문자 데이터로 변환하는 TO_CHAR 함수

  • 자료형을 문자로 변환하는 함수로 TO_CHAR([데이터], [포멧])으로 작성하면 된다.
연 월 일에 대한 포맷
CC 세기 MONTH 월(언어별 월 이름 전체)
YYYY,RRRR 연(4자리) DD 일(2자리 숫자)
YY,RR 연(2자리) DDD 1년 중 며칠
MM 월(2자리) DY 요일(언어별 요일 이름 약자)
MON 월(언어별 월 이름 약자) DAY / W 요일(언어별 요일 이름 전체) / 1년 중 몇 째주
시간 형식에 대한 포맷
HH24 24시간으로 표현한 시간 HH,HH12 12시간으로 표현한 시간
MI / SS 분 / 초 AM,PM,A.M,P.M 오전, 오후 표시
## 연/월 포맷
SELECT SYSDATE,
TO_CHAR(SYSDATE, 'MM'),
TO_CHAR(SYSDATE, 'YYYY'),
TO_CHAR(SYSDATE, 'DD')
FROM TABLE;
## 시간 포맷
SELECT SYSDATE,
TO_CHAR(SYSDATE, 'HH'),
TO_CHAR(SYSDATE, 'HH24'),
TO_CHAR(SYSDATE, 'HH:MI:SS'),
TO_CHAR(SYSDATE, 'HH:MI:SS AM')

2-4. 문자 데이터를 숫자 데이터로 바꿔주는 TO_NUMBER 함수

  • 문자를 숫자로 바꿔주는 수행을 해준다. TO_NUMBER(데이터, 숫자형태)의 형태로 작성
    SELECT TO_NUMBER('1,300','999,999') FROM TABLE; ## 이러면 6자리 숫자로 이루어진 형태로 1,300을 반환​

2-5. 문자 데이터를 날짜 데이터로 변환

  • TO_DATE 함수로 문자를 날짜 데이터로 변환할 수 있다.
  • TO_DATE(데이터, 날짜 형태)로 입력하면 된다. 기본적으로는 YYYY-MM-DD가 있다.
SELECT TO_DATE('2018-09-10', 'YYYY-MM-DD') FROM TABLE;


## 이외 형식들
# YY/MM/DD
# RR/MM/DD 등..

 


3. NULL 처리 및 조건문 함수

3-1. NULL 처리 함수 NVL / NVL2

  • NVL 함수는 IFELSE 함수와 비슷한 포맷으로 구성되어 있다. 다만, 조건은 무조건 NULL값으로 고정
  • NVAL(데이터, NULL일 경우 반환할 데이터)
SELECT NVL(COMM,0) FROM TABLE ## NULL이면 0으로 반환 아니면 그냥 반환
  • NVL2는 NULL일 경우/NULL이 아닐 경우에 대한 RETURN값을 전부 정할 수 있는 함수
  • NVL2(데이터, TRUE일 경우, FALSE일 경우)
    SELECT NVL2(COMM,'O','X') FROM TABLE;​

3-2. 상황에 따른 데이터를 반환하는 DECODE, CASE함수

  • 기본적으로 둘 다 MUTATE IF, IF, SWITCH와 같은 함수류들과 비슷한 작업을 수행한다.
  • DECODE의 경우 DECODE(데이터, 조건1, 조건1에 따른 반환값, 조건2, 조건2에 대한 반환값 ...)으로 구성
  • CASE의 경우, 선언한 뒤 변수를 입력하고, WHEN 조건 THEN 출력값의 형태로 작성한다. (마무리는 항상 END)
## DECODE의 형태
SELECT DECODE(JOB,
'MANAGER', SAL*1.1,
'EMPLOYER', SAL * 1.0) FROM TABLE;

## CASE 형태
SELECT EMP,
CASE JOB ## CASE로 시작
WHEN MANAGER THEN SAL*1.1
WHEN EMPLOYER THEN SAL*1.0
ELSE SAL*0.5
END ## END로 마무리
FROM TABLE;

4. 연습문제 풀이

4-1. 

  • 조건1 : EMPNO열은 사원 이름이 다섯 글자이며, 여섯 글자 미만인 사원 정보 출력
  • 조건2 : MASKING_EMPNO 열에는 사원 번호 앞 두 자리 외 뒷자리를 *로 출력
  • 조건3 : MASKING_ENAME 열에는 사원 이름의 첫 글자만 보여주고 나머지 글자수만큼 *로 출력
## 내 풀이 (ORACLE를 다시 깔고 나서 확인이 가능할 것 같다)
SELECT EMPNO, REPLACE(EMPNO, SUBSTR(EMPNO,3,2),'*') AS MASKING_EMPNO
ENAME,
REPLACE(ENAME, SUBSTR(ENAME,2,4),"*") AS MASKING_ENAME

FROM EMP
WHERE LENGTH(ENMPNO) >= 5 AND LENGTH(EMPNO) <6;

## 답안
SELECT EMPNO,
       RPAD(SUBSTR(EMPNO, 1, 2), 4, '*') AS MASKING_EMPNO,
       ENAME,
       RPAD(SUBSTR(ENAME, 1, 1), LENGTH(ENAME), '*') AS MASKING_ENAME
 FROM  EMP
 WHERE LENGTH(ENAME) >= 5
   AND LENGTH(ENAME) < 6;
  • SUBSTR을 이용해서, 앞 글자만 뽑고 나머지를 RPAD를 활용하여 덮어씌운 것으로 확인!
  • RPAD는 DATA, 개수, 문자로 반환값을 받는다.

4-2.

  • 조건1: 하루 근무를 8시간을 봄
  • 조건2: 사원들의 하루 급여와 시급을 게산하여 출력
  • 조건3: 하루 급여는 소수점 세 번째자리에서 버리고, 시급은 두 번째 소수점에서 반올림
## 내 코드 (확인 필요)
SELECT EMPNO,ENAME,SAL,
TRUNC(SAL/(21.5),2) AS DAY_PAY,
ROUND(SAL/(21.5*8),1) AS TIME_PAY
FROM EMP;

## 정답
SELECT EMPNO, ENAME, SAL,
       TRUNC(SAL / 21.5, 2) AS DAY_PAY,
       ROUND(SAL / 21.5 / 8, 1) AS TIME_PAY
  FROM EMP;
  • 중요한 것은 FLOOR가 아니라 TRUNC함수를 썼다는 점. FLOOR은 파라미터가 하나 뿐!
  • 또한 문항에서 '~ 번째에서' 반올림이기 때문에 그 앞자리를 기준으로 파라미터를 작성해야 함

4-3.

  • 조건1 : 입사일을 기준으로 3개월이 지난 첫 월요일에 정직원이 됨
  • 조건2 : 정직원이 되는 날짜를 YYYY-MM-DD 형식으로 출력
  • 추가 수당이 없는 사원의 추가 수당은 N/A로 출력
## 내 답안 (틀림)
SELECT EMPNO, ENAME,HIREDATE,
TO_DATE(NEXT_DAY(ADD_MONTHS(HIREDATE,3),'월요일'),'YYYY-MM-DD') AS R_JOB
NVL(COMM, 'N/A') AS COMM
FROM EMP;

## 정답
SELECT EMPNO, ENAME, HIREDATE,
       TO_CHAR(NEXT_DAY(ADD_MONTHS(HIREDATE, 3), '월요일'), 'YYYY-MM-DD') AS R_JOB,
       NVL(TO_CHAR(COMM), 'N/A') AS COMM
  FROM EMP;
  • 보면, TO_DATE가 아닌 TO_CHAR로 표현했으며, COMM 열의 경우 미리 CHARACTER로 바꾼 다음 NVL 함수를 사용
  • 실제로 코드 돌렸을 때, 아마 자료형태 때문에 오류가 생기지 않을까 생각이 든다.
  • 항상 하나의 자료형만 같게 되니(열), 자료형태 맞추는걸 생각해두자!

4-4. 

## 내 답안
SELECT EMPNO, ENAME, MGR,
CASE TO_CHAR(MGR)
WHEN MGR IS NULL THEN '0000'
WHEN SUBSTR(MGR,1,2) = '75' THEN '5555'
WHEN SUBSTR(MGR,1,2) = '76' THEN '6666'
WHEN SUBSTR(MGR,1,2) = '77' THEN '7777'
WHEN SUBSTR(MGR,1,2) = '78' THEN '8888'
ELSE TO_CHAR(MGR)
END AS CHG_GMR
FROM EMP;

## 정답
SELECT EMPNO, ENAME, MGR,
       CASE
          WHEN MGR IS NULL THEN '0000'
          WHEN SUBSTR(MGR, 1, 2) = '78' THEN '8888'
          WHEN SUBSTR(MGR, 1, 2) = '77' THEN '7777'
          WHEN SUBSTR(MGR, 1, 2) = '76' THEN '6666'
          WHEN SUBSTR(MGR, 1, 2) = '75' THEN '5555'
          ELSE TO_CHAR(MGR)
       END AS CHG_MGR
  FROM EMP;
  • 마찬가지로 자료형태(CHR) 잘 신경써주면 되며, 항상 조건 앞 뒤로 문장이 말이 되는지를 확인하자!