본문 바로가기
클라우드 활용 자바개발자 양성과정/02. 데이터베이스 활용

02. SELECT (함수)

by moca7 2024. 7. 17.

 

 

 

ㅁ < 함수 FUNCTION >

- 전달된 값을 가지고 특정 연산 수행 후 결과를 반환해줌.

- 전달된 값의 수와 반환된 값의 수를 통해 종류가 나뉨.

- 단일행 함수 : N개의 값을 읽어들여 N개의 결과값 반환 (매 행마다 함수 실행 결과를 반환)

- 그룹 함수 : N개의 값을 읽어들여 1개의 결과값 반환 (그룹을 지어 그룹별로 함수 실행 결과를 반환)

- 결과의 행 수가 다르기 때문에 단일행 함수와 그룹함수는 함께 사용할 수 없음.

- SELECT절, WHERE절, ORDER BY절, GROUP BY절, HAVING절 + DML 구문 등 다양한 곳에서 작성 가능.

- 그룹 함수는 5개 정도. SUM, AVG, COUNT, MAX, MIN

- 단일행 함수는 엄청 많다.

 

 

어떤 타입으로 반환하는지를 잘 알아야 중첩해서 잘 쓸 수 있다.

 

 

 

 

ㅁ < 문자 처리 함수 >
- 문자 데이터를 가지고 연산을 하는 함수.
- 반환 결과는 문자 또는 숫자가 될 수 있음.
- LENGTH('문자열값' | 컬럼) : 문자열의 글자 수를 NUMBER 타입으로 반환.
- LENGTHB('문자열값' | 컬럼) : 문자열의 바이트 수를 NUMBER 타입으로 반환.

ㅁ 참고
- 자음만이든 모음만이든 결합된 형태든 한글 한 글자당 3바이트.
- 영문, 숫자, 특수문자는 한 글자당 1바이트.

 

 

 

 

 

ㅁ 예제

SELECT LENGTH('오라클'), LENGTHB('오라클'),
               LENGTH('ORACLE'), LENGTHB('ORACLE')
FROM DUAL;

 

- SELECT절은 뭐가 됐든 FROM절이 필수.

- 3, 9, 6, 6

- 영문자는 글자 수와 바이트 수가 같다.

 

ㅁ 예제2

SELECT *
FROM EMPLOYEE
WHERE LENGTH(EMAIL) = 13;

 

- 이메일이 13글자인 사원들의 모든 컬럼 조회

- WHERE절에도 함수 사용 가능.

 

 

 

 

 

ㅁ INSTR

- 문자열로부터 특정 문자의 시작위치를 찾아서 NUMBER 타입으로 반환

- 시작위치가 0부터 시작하지 않고 1부터 시작한다.

- INSTR('문자열값' | 컬럼, '찾고자하는문자')                                                 //      이 두 개는 필수

- INSTR('문자열값' | 컬럼, '찾고자하는문자', 찾을위치의시작값)                  //      찾을위치의시작값 생략 가능

- INSTR('문자열값' | 컬럼, '찾고자하는문자', 찾을위치의시작값, 순번)         //      순번만 생략 가능

 

 

ㅁ 예제

SELECT INSTR('AABAACAABBAA', 'B') 

FROM DUAL;

 

- 찾을 위치의 시작값은 1이 기본값. 순번(B가 3개인데 첫번째 B의 위치찾기)도 1이 기본값. 

 

 

ㅁ 예제2 (EMAIL이  _ 앞에 3글자인 사원 조회)

SELECT *
FROM EMPLOYEE

WHERE EMAIL LIKE '___!_' ESCAPE '!';

 

SELECT *
FROM EMPLOYEE
WHERE INSTR(EMAIL, '_') = 4;            //           이렇게도 가능. 숫자를 리턴한다.

 

 

 

 


ㅁ SUBSTR

- 문자열에서 특정 문자열을 추출해서 CHARACTER 타입으로 반환.

- SUBSTR('문자열값' | 컬럼, 시작위치)

- SUBSTR('문자열값' | 컬럼, 시작위치, 추출할문자갯수)            //           LENGTH생략시 끝까지.

- 시작위치가 음수일 경우, 맨 뒤가 -1이다.

- 추출할 문자 갯수(LENGTH)를 부적절하게 제시(음수 제시)시, 오류나지는 않고 NULL 반환.

 

 

ㅁ 예제

SELECT SUBSTR('SHOWMETHEMONEY', 7)
FROM DUAL;

 

-   SUBSTR('SHOWMETHEMONEY', 7)

 THEMONEY

 

 

ㅁ 예제2 (남성인 사원들 조회)

SELECT EMP_NAME, EMP_NO
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO, 8, 1) = '1'  OR   SUBSTR(EMP_NO, 8, 1) = '3';

 

SELECT EMP_NAME, EMP_NO
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO, 8, 1) IN ('1', '3');

 

 

ㅁ 예제3 (이메일 @ 이전까지만 추출)

SELECT EMP_NAME, EMAIL, SUBSTR(EMAIL, 1, INSTR(EMAIL, '@')-1)
FROM EMPLOYEE;

 

- 함수 중첩 사용 가능하다.

 

 

ㅁ 예제4 (주민번호를 900113-2****** 형식으로 조회)

SELECT EMP_NAME, EMP_NO, SUBSTR(EMP_NO, 1, 8) || '******'
FROM EMPLOYEE;

 

 

 

 

 

ㅁ LPAD, RPAD

- 문자열에 특정 문자를 왼쪽 또는 오른쪽에 덧붙여서 CHARACTER 타입으로 반환

- LPAD | RPAD (STRING, 최종적으로반환할문자의길이)                       //       생략시  공백으로  채워짐

- LPAD | RPAD (STRING, 최종적으로반환할문자의길이, 덧붙이고자하는문자)

 

 

ㅁ 예제 (주민번호를 900113-2****** 형식으로 조회)

SELECT EMP_NAME, EMP_NO, RPAD( SUBSTR(EMP_NO, 1, 8),  14,  '*' )
FROM EMPLOYEE;

 

 

 

 

 

ㅁ LTRIM, RTRIM

- 문자열에서 왼쪽 또는 오른쪽에 특정 문자들을 제거한 나머지 문자열을 CHARACTER 타입으로 반환.

- LTRIM | RTRIM (STRING)                //           생략시 공백 제거.

- LTRIM | RTRIM (STRING, 제거하고자하는문자들)

- 제거하고자하는문자들에 있는 문자들을 전부 제거.

'0123456789'면 모든 숫자 제거.

 

 

ㅁ 예제

SELECT EMP_NAME, EMAIL, RTRIM(EMAIL, '@br.com')
FROM EMPLOYEE;

 

- 단점이 @ 바로 왼쪽에 b, r, ., c, o, m 있으면 그것도 생략됨. 한번 막혀야 멈춤.

REPLACE(EMAIL, 'br.com', '') 사용할 수 있다.

 

 

 

 

 

ㅁ TRIM

- 기본적으로 양 옆의 공백 제거. 가운데에 있는 공백은 제거 안 됨.

- LTRIM, RTRIM과 다르게 제거하고자하는문자를 한 개만 제시 해야 한다.

- LEADING, TRAILING 생략 가능. 

 

 

 

 

 

ㅁ LOWER, UPPER, INITCAP

- 자바에서의 toLowerCase(), toUpperCase()와 비슷하다.

 

 

 

 

 

ㅁ 예제

SELECT '가나다라' || 'ABCD'

FROM DUAL;

 

-    '가나다라' || 'ABCD'

1   가나다라ABCD

 

 

 

 

 

ㅁ 예제 (사원명, 입사년도 2자리만)

SELECT EMP_NAME, SUBSTR(HIRE_DATE, 1, 2) 

FROM EMPLOYEE;

 

- 문자열이 와야 함. 날짜 타입이라 자동 형변환이 일어났다. ( 날짜타입 -> 문자타입 )

 

 

ㅁ 예제 (사원명, 생년월일 XX년 XX월 XX일)

SELECT EMP_NAME, EMP_NO, SUBSTR(EMP_NO, 1, 2) || '년' ||
                                                      SUBSTR(EMP_NO, 3, 2) || '월' ||
                                                      SUBSTR(EMP_NO, 5, 2) || '일'   생년월일
FROM EMPLOYEE;

 

 

ㅁ 예제 (사원명, 급여 만원 단위로)

SELECT EMP_NAME, SALARY, SUBSTR(SALARY, 1, LENGTH(SALARY)-4)
FROM EMPLOYEE;

 

 

 

 

 

ㅁ < 숫자 처리 함수 >

- 숫자 데이터를 가지고 연산을 수행하는 함수.

- 반환 결과 또한 숫자이다.

 

 

 

 

 

ㅁ 

SELECT 10 / 3 FROM DUAL;                     //           3.333333333333

SELECT MOD(10, 3) FROM DUAL;           //           1

 

 

 

 

 

ㅁ 예제 (사원명, 입사일 근무일 수)

SELECT EMP_NAME, HIRE_DATE, TRUNC(SYSDATE - HIRE_DATE)

FROM EMPLOYEE;

 

- 날짜 간의 연산은 시분초도 연산되어서 소수점 아래로 매우 지저분함.

 

 

 

 

ㅁ SELECT CEIL(123.000) FROM DUAL;        //         이건 123. 소수로 취급 안 함. 

 

 

 

 

 

 

 

 

ㅁ < 날짜 처리 함수 >

- 날짜 데이터를 가지고 연산을 수행한다.

- 반환값은 날짜 또는 숫자이다. (잘 알아야 한다)

 

 

 

 


ㅁ SYSDATE

- 현재 시스템의 날짜 및 시간 반환

- 시분초 정보는 더블클릭 후 연필 아이콘 클릭하면 나온다.

안나오면 날짜 타입이 아닌 것이다.

 

 

ㅁ 예제

SELECT SYSDATE
FROM DUAL;

 

-  SYSDATE

1  24/07/17

 

 

ㅁ 예제2 (2일 전 날짜)

SELECT SYSDATE - 2
FROM DUAL;

 

-  SYSDATE-2

1   24/07/15

 

 

 

 

 

ㅁ MONTHS_BETWEEN(DATE1, DATE2)

- 양수의 결과를 보고 싶으면 처음 인자가 더 커야 함.

- 내부적으로 DATE1 - DATE2 연산 후 나누기 30, 31이 진행됨.

일 단위로 나오고, 이것도 시분초까지 연산되어서 소수점 아래로 지저분함.

 

 

ㅁ 예제 (사원명, 입사일, 근무일수, 근무개월수)

SELECT EMP_NAME, HIRE_DATE, TRUNC( SYSDATE - HIRE_DATE) "근무일수", 
                                                           TRUNC( MONTHS_BETWEEN(SYSDATE, HIRE_DATE) ) "근무개월수"
FROM EMPLOYEE

ORDER BY 4 DESC;

 

- 열 별칭을 정의할 때, 별칭에 한글을 사용할 경우 큰 따옴표로 감싸야 합니다.

 

 

 

 

 

 

ㅁ NEXT_DAY

- 특정 날짜 이후에 가까운 요일의 날짜를 DATE 타입으로 반환.

- NEXT_DAY( DATE, 요일(문자 혹은 숫자) )

- 오라클) 일요일이 1, 토요일이 7.

- 자바) 월요일이 1, 일요일이 7.

 

 

ㅁ 언어 체계 변경

ALTER SESSION SET NLS_LANGUAGE = AMERICAN;

SELECT SYSDATE, NEXT_DAY(SYSDATE, 'FRIDAY')

FROM DUAL;         //        정상 실행

 

 

 

 

ㅁ LAST_DAY로 근무일 수 계산(주말 제외)

- 결과 값이 숫자로 나오는 이유는 날짜 간의 차이를 일 단위로 계산하기 때문입니다. 데이터베이스에서는 일반적으로 날짜 간의 차이를 일 수로 계산하여 반환합니다.

 

 

 

 

ㅁ EXTRACT

- 숫자로 반환함.

 

 

ㅁ 예제

SELECT  EMP_NAME

             ,  EXTRACT(YEAR FROM HIRE_DATE) "입사년도"

             ,  EXTRACT(MONTH FROM HIRE_DATE) "입사월"

             ,  EXTRACT(DAY FROM HIRE_DATE) "입사일"

   FROM  EMPLOYEE;

 

- 이렇게 컴마까지 내려서 작성하는 경우가 많음.

문장 단위로 주석처리(--)하기 편해서.

- 마지막 세미콜론만 한 줄 내리는 경우도 있음. 주석처리 하기 편하려고.

 

 

 

 

 

 

ㅁ < 형변환 함수 >

- 날짜, 숫자, 문자 데이터를 다른 타입으로 변환시켜주는 함수

 

 

 

 

ㅁ TO_CHAR

- 숫자나 날짜타입 데이터 값을 CHARACTER 타입으로 변환시켜서 반환한다.

- 웹개발 하면서 많이 쓴다. 날짜를 문자열로 변환할 때.

 

 

ㅁ 예제

SELECT TO_CHAR(1234)

FROM DUAL;             //         1234

 

- 질의 결과는 1234지만 엄연히 문자임. 따옴표 없어도.

- 보통 문자는 왼쪽 정렬, 숫자는 오른쪽 정렬.

 

 

ㅁ 예제2

SELECT TO_CHAR(1234, '99999')

FROM DUAL;             //     ' 1234'가 조회됨.

 

SELECT TO_CHAR('00000')

FROM DUAL;            //      '01234'가 조회됨.

 

- 99999, 00000 다섯자리 문자열로 변환하겠다는 의미. 

- 99999는 빈 자리를 공백으로 채움.       

- 00000은 빈 자리를 0으로 채움.          

 

 

ㅁ 예제3

SELECT TO_CHAR(1234, 'L99999')

FROM DUAL;            //       '₩1234'  


- L은 LOCAL. 현재 설정된 나라의 화폐단위가 붙음. 

달러 붙이고 싶으면 L대신 $.

- 빈 자리 공백 X.

- 몇자리가 올진 모르지만 화폐단위 붙이는 용도. L99999999999999 이렇게 쓰기도 함.

 

 

SELECT TO_CHAR(12341234, 'L999,999,999') 

FROM DUAL;            //       '₩12,341,234'

 

- 컴마 삽입

 

 

 

ㅁ 예제4

SELECT SYSDATE

FROM DUAL;                //      24/07/17

 

SELECT TO_CHAR(SYSDATE) 

FROM DUAL;                 //      24/07/17     (문자임)

 

SELECT TO_CHAR(SYSDATE, 'AM HH:MI:SS')

FROM DUAL;                 //       오후 02:49:27

 

SELECT TO_CHAR(SYSDATE, 'PM HH24:MI:SS')

FROM DUAL;                 //       오후 14:49:33         (현재 시간이라 똑같이 오후 나온 듯)

 

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD DAY')

FROM DUAL;                 //       2024-07-17 수요일

 

 

ㅁ 예제5 (24년 07월 17일)

SELECT  TO_CHAR(SYSDATE, 'YYYY YY RRRR RR YEAR')         //    2024 24 2024 24 TWENTY TWENTY-FOUR
            ,   TO_CHAR(SYSDATE, 'MM MON MONTH RM')                //     07   7월   7월   VII
            ,   TO_CHAR(SYSDATE, 'DDD DD D')                                   //    199(년 기준 몇일째인지) 17(월 기준) 4(주 기준)
            ,   TO_CHAR(SYSDATE, 'DAY DY')                                       //     수요일 수             
FROM DUAL;      

 

 

ㅁ 예제6

SELECT EMP_NAME, TO_CHAR( HIRE_DATE, 'YYYY년 MM월 DD일 (DY) )           //         에러

FROM EMPLOYEE;

 

SELECT EMP_NAME, TO_CHAR( HIRE_DATE, 'YYYY"년" MM"월" DD"일" (DY)' )
FROM EMPLOYEE;                   

 

- 1990년 02월 06일 (화)

 

 

 

 

 

 

 

ㅁ TO_DATE

- 숫자, 문자 타입 데이터를 DATE 타입으로 변환시켜서 반환.

- TO_DATE(NUMBER | CHARACTER, [포맷])

- 8자리 숫자 제시시 4개 년도, 2개 월, 2개 일.

- 6자리 숫자 제시시 2개 년도, 2개 월, 2개 일.

 

 

ㅁ 예제

SELECT TO_DATE(20101255) 

FROM DUAL; 

 

- 55일은 없기 때문에 오류남.

 

 

SELECT TO_DATE(070101) 

FROM DUAL; 

 

- 자바에서와 마찬가지로, 숫자 앞에 0붙이면 그냥 없는 걸로 인식함.

5자리 숫자로 인식해서 오류남.

 


SELECT TO_DATE('070101') 

FROM DUAL; 

 

- 오류 안남. 문자열로 인식.

 

 

ㅁ 예제2

SELECT TO_DATE('041030 143030')

FROM DUAL;

 

- 시분초로 하고 싶었는데 오류남.

 

 

SELECT TO_DATE('041030 143030', 'YYMMDD HH24MISS')

FROM DUAL;

 

- 출력은 04/10/30만 되지만 더블클릭 해보면 시분초 정보도 있음.

 

 

ㅁ 예제3

SELECT TO_DATE('980630', 'YYMMDD')

FROM DUAL;

 

- 출력은 98/06/30으로 되지만 더블클릭 해보면 2098년도임. 

 

SELECT TO_DATE('980630', 'RRMMDD')

FROM DUAL;

 

-  출력은 98/06/30으로 되지만 더블클릭 해보면 1998년도임. 

 

- YY : 무조건 현재세기로 반영

- RR : 두자리 년도 값이 50 미만일 경우 현재 세기, 50 이상일 경우 이전 세기.

 

 

 

 

 

ㅁ TO_NUMBER

- CHARACTER 타입의 데이터를 NUMBER 타입으로 변환해서 반환.

- DATE 타입은 불가.

 

 

ㅁ 예제

SELECT TO_NUMBER('01234')

FROM DUAL;

 

- 1234가 출력됨.

 

 

ㅁ 오라클은 자동 형변환 지원이 잘 되어있어서 문자 출력해도 자동으로 숫자 출력되는 경우도 많음.

SELECT '1000000' + '5000000' 

FROM DUAL;

 

- 6000000이 출력됨. 자바처럼 10000005000000가 아니라.

- 저기에 컴마 등 특수문자가 있으면 자동형변환 안 됨. 오직 문자열에 숫자만 있는 경우에만. 

 

 

ㅁ 예제2

SELECT TO_NUMBER('1,000,000', '9,999,999') + TO_NUMBER('5,000,000', '9,999,999')

FROM DUAL;

 

- 숫자 포맷쓰면 가능

 

 

 

 

 

 

ㅁ < NVL 처리 함수 >

- NVL(컬럼, 반환값)

해당 컬럼값이 존재할 경우 컬럼값 반환.

해당 컬럼값이 NULL일 경우 반환값 반환.

 

- NVL2(컬럼, 반환값1, 반환값2)

해당 컬럼값이 존재할 경우 반환값1 반환.

해당 컬럼값이 NULL일 경우 반환값2 반환.

 

 

ㅁ 예제

SELECT EMP_NAME, NVL(BONUS, '없음')

FROM EMPLOYEE;

 

- 오류. BONUS 컬럼값이 NUMBER타입이라서 CHARACTER 타입으로 반환하게끔 작성해서. 

 

 

ㅁ 예제2

SELECT EMP_NAME, ( SALARY + SALARY*NVL(BONUS,0) ) * 12

FROM EMPLOYEE;

 

- 잘 됨.

 

 

ㅁ NULLIF 함수

- NULLIF(비교대상1, 비교대상2)

두 개의 값이 일치하면 NULL 반환.

두 개의 값이 일치하지 않으면 비교대상1 반환.

- 이런 것도 있다.

 

 

 

 

 

 

ㅁ DECODE

- DECODE(비교대상, 비교값1, 결과값1, 비교값2, 결과값2, ..., DEFAULT 결과값 )

- 비교대상 값을 가지고 특정 값과 일치하는지 비교 후 해당 결과값 반환.

- 비교대상을 꼭 컬럼값일 필요는 없고 연산식 가능.

 

 

ㅁ 예제

SELECT EMP_NAME, JOB_CODE, DECODE(JOB_CODE, 'J7', SALARY*1.1, 
                                                                                                 'J6', SALARY*1.15, 
                                                                                                 'J5', SALARY*1.2, 
                                                                                                 SALARY*1.05)
FROM EMPLOYEE;

 

- 마지막 디폴트는 조건을 안 쓴다.

- 반환되는 값들의 타입들을 전부 일치시켜야 한다.

 

 

 

 

 

ㅁ CASE WHEN THEN END

- 함수는 아니지만 선택함수처럼 사용할 수 있는 문법

 

- CASE 비교대상                                       //          비교대상과 비교값들이 동등한지 비교

  WHEN 비교값1 THEN 결과값1

  WHEN 비교값2 THEN 결과값2

  ...

  [ ELSE 결과값N ]

  END

 

- CASE 

  WHEN 조건식1 THEN 결과값2

  WHEN 조건식1 THEN 결과값2

  ...

  [ ELSE 결과값N ]

  END

 

 

ㅁ 예제 (동등비교)

SELECT EMP_NAME

             , CASE SUBSTR(EMP_NO, 8, 1)

               WHEN '1' THEN '남'

               WHEN '2' THEN '여'

               END "성별"

FROM EMPLOYEE;

 

 

ㅁ 예제 (조건비교)

SELECT EMP_NAME

             , CASE 

               WHEN SALARY >= 5000000 THEN '고급'

               WHEN SALARY >= 3500000 THEN '중급'

               ELSE '초급'

               END "등급"

FROM EMPLOYEE;

 

 

 

 

 

 

 

 

 

그룹 함수는 NULL을 제외하고 계산한다.

 

ㅁ SUM, AVG, COUNT는 NUMBER를 받아서 NUMBER를 반환함.

- MAX, MIN은 NUMBER뿐 아니라 문자, 날짜 타입을 받아서 문자, 날짜 타입을 반환할 수도 있다.

- MIN 함수는 그룹 내에서 가장 이른 날짜를 반환합니다. (가장 예전 날짜)

- MIN 함수는 그룹 내에서 가장 작은 문자열을 반환합니다. (알파벳 빠른 순)

반환되는 데이터 타입은 해당 컬럼의 데이터 타입과 동일합니다.

 

 

 

 

 

ㅁ EMPLOYEE 전 사원의 총급여합

SELECT SUM(SALARY)

FROM EMPLOYEE

 

- 전체 사원이 '한 그룹'으로 묶임.

 

 

 

 

 

ㅁ 

SELECT MIN(EMP_NAME)

            ,  MIN(SALARY)

            ,  MIN(HIRE_DATE)

FROM EMPLOYEE;

 

 

- 이 결과는 각각 다 별개임. 김해줄의 연봉과 입사일이 아님.

 

 

 

 

- COUNT(*) 조회된 결과의 모든 행 개수를 세서 반환                                                        NULL O 중복 O        

- COUNT(컬럼) 조회된 컬럼의 값들을 개수를 세서 반환                                                   NULL X 중복 O        

- COUNT(DISTINCT 컬럼) 해당 컬럼값에서 중복을 제거한 후 개수를 세서 반환             NULL X 중복 X          

 

ㅁ 비교

SELECT COUNT(*)

FROM EMPLOYEE;                                                                            //          23

 

SELECT COUNT(DEPT_CODE)

FROM EMPLOYEE;                                                                            //          21

 

SELECT COUNT(DISTINCT DEPT_CODE)

FROM EMPLOYEE;                                                                             //          6

 

 

SELECT DISTINCT DEPT_CODE                                                      //     (null)을 포함한 7개의 행

FROM EMPLOYEE;

 

SELECT COUNT(DISTINCT NVL(DEPT_CODE, '없음'))                   //          7

FROM EMPLOYEE;

 

 

 

 

 

ㅁ 현재 테이블의 전체 행 개수 세기

SELECT COUNT(*)

FROM EMPLOYEE;

 

- COUNT(*)

1            23

 

 

ㅁ *과 COUNT(*)의 차이

 

 

 

 

ㅁ 보너스를 받는 남성 사원의 수

- 물론 WHERE에 조건을 하나(AND BONUS IS NOT NULL) 더 붙이고 COUNT(*)를 할 수도 있지만 이렇게도 가능하다.

 

 

 

'클라우드 활용 자바개발자 양성과정 > 02. 데이터베이스 활용' 카테고리의 다른 글

05. SUBQUERY  (0) 2024.07.19
04. JOIN (조인문)  (0) 2024.07.18
03. GROUP BY & HAVING  (0) 2024.07.18
01. SELECT (기본 문법)  (0) 2024.07.16
0. 오라클 설치  (0) 2024.07.15