DBMS

[DBMS_09] 함수 (그룹 숫자 문자 날짜)

korany 2023. 3. 7. 11:49

1. 그룹함수

여러개의 행 또는 테이블 전체에 대하여 하나의 결과만을 가져오는 함수

그룹함수 일반컬럼과 함께 사용될 수 없다

1) AVG() : 평균 구하는 함수

2) COUNT() : 행의 개수를 반환하는 함수 (null 값은 무시함)

3) MAX() : 최대값을 구하는 함수

4) MIN() : 최소값을 구하는 함수

5) SUM() : 총 합을 구하는 함수

 

더보기

 

2) COUNT() : 행의 개수를 반환하는 함수 (null 값은 무시함)

-- 그룹함수와 일반컬럼은 함께 사용될 수 없다

SELECT COUNT(commission_pct), salary FROM employees;

 

-- 사원 테이블에서 사번을 가지고있는 모든 사원의 수를 출력

SELECT COUNT (employee_id) FROM employees;​

 

--사원테이블의 모든 사원의 수를 출력

SELECT COUNT (*) FROM employees;

 

--아래의 쿼리문은 부서번호를 가지고있지 않은 인원이 1명 존재하기 때문에 전체인원인 107명을 출력할 수 없다

SELECT COUNT (department_id) FROM employees;

 

--사원테이블에서 관리자 id를 가진 사원 수를 출력

SELECT COUNT(manager_id) FROM employees;

 

-- 사원테이블에서 전체 사원수와 보너스를 받는 사원의 수를 각각 출력

*그룹함수는 일반컬럼과는 함께 사용할 수 없지만, 그룹함수는 중복 사용할 수 있다!

SELECT COUNT(*) allCnt, COUNT(commission_pct) comm
FROM employees;

 

-- 직종이 'SA_REP' 인 사원들의 수와 평균 급여와, 최고급여, 최저급여, 급여의 총합계를 화면에 출력

SELECT COUNT(*) SR_COUNT, AVG(salary),MAX(salary), MIN(salary), SUM(salary)
FROM employees WHERE job_id = 'SA_REP';

 


 


2. 숫자함수

1) ROUND() : 반올림

2) TRUNC() : 버림

3) POWER() : 제곱

4) MOD() : 나머지 값

더보기

 

SELECT ROUND(0.12345678,2),
ROUND(3.141592,3) FROM dual;

 

-- 숫자함수는 그룹함수를 포함 할 수있다!

SELECT ROUND(AVG(salary),2) FROM employees;

 


--4의 2제곱

SELECT POWER(4,2) FROM dual;

-- 10%3 나머지

SELECT MOD(10,3) FROM dual;

 


-- 10/3 몫을 소숫점 두자리까지 구하고싶다

SELECT TRUNC(10/3,2) FROM dual;

--짝수 사번을 가진 사원들의 사원이름을 출력

SELECT employee_id, first_name FROM employees
WHERE MOD(employee_id,2) = 0;

 


 

3. 문자함수

1.) initcap() :첫 문자를 대문자로 변환

2) lower() : 대문자 -> 소문자

3) upper() : 소문자 -> 대문자

4) substr() : 특정문장 잘라내기

5) replace() : 필요한 문장 교체

6) length() : 문장의 길이

더보기

1. initcap() :첫 문자를 대문자로 변환

SELECT initcap('goodmorning') FROM dual;

--initcap은 공백이나 /를 구분자로 인식한다

SELECT initcap('good/morning') FROM dual;

2. lower() : 대문자 -> 소문자

SELECT lower('GOOD MORNING') FROM dual;

문자함수는 일반컬럼과 사용가능! 그룹함수만 안됨!!

SELECT first_name, lower(first_name) FROM employees;

대소문자 상관없이 비교하고싶을땐 

모두 대문자로 만들어 비교하거나 모두 소문자로 만들어 비교하기

SELECT first_name FROM employees
WHERE lower(first_name) = 'michael';

3. upper() : 소문자 -> 대문자

SELECT UPPER('hi hello') FROM dual;

4. substr() : 특정문장 잘라내기

SELECT substr('good morning', 1, 4) FROM dual;

 


-- 입사일, 입사년도만 출력

SELECT hire_date, substr(hire_date, 7, 10) HIRE_YEAR FROM employees;

5. replace() : 필요한 문장 교체

-- 

SELECT replace('good morning tom', 'o','i') FROM dual;
SELECT replace('good morning tom', 'tmo','john') FROM dual;

6. length() : 문장의 길이

--사원테이블에서 이름이 여섯글자 초과인 사원들의 이름만 출력

SELECT first_name FROM employees
WHERE length(first_name) > 6;

 

 

 


4. 날짜 함수

1) sysdate() : 오늘 날짜 키워드

2) months_between() : 날짜와 날짜 사이의 개월 수

3) add_months() : 특정 날짜로 부터 몇개월이 경과했는지 확인

4) to_char() : 원하는 형식으로 날짜 포멧을 변경하는 함수

더보기

1) sysdate() : 오늘 날짜 키워드

SELECT sysdate FROM dual;

2) months_between() : 날짜와 날짜 사이의 개월 수

--사원테이블에서 모든 사원들이 입사일로부터 오늘까지 몇개월이 경과했는지 출력

SELECT first_name, sysdate, hire_date, months_between( sysdate, hire_date) FROM employees;

 

-- '11/04/2020' 부터 오늘까지의 개월 수 출력

SELECT months_between( sysdate,'11/04/2020') FROM dual;

---- 위의 문제 소숫점 삭제 하기 '11/04/2020' 부터 오늘까지의 개월 수 출력

SELECT TRUNC(months_between(sysdate, '11/04/2020')) FROM dual;

*trunc 뒤의 소숫점을 없애고 싶을땐 아예 생략 가능하다!


-- 입사기간이 200개월 이상인 사원들의 이름, 입사일, 근무개월수를 조회하시오 ( 단, 근무개월수는 소수점 이하 자릿수를 삭제)

SELECT first_name, hire_date, trunc( months_between(sysdate, hire_date) , 0) 
FROM employees
WHERE  months_between(sysdate, hire_date) >= 200;

3) add_months() : 특정 날짜로 부터 몇개월이 경과했는지 확인

-- 오늘 날짜로부터 6개월 뒤의 날짜를 출력


-- 사번이 120번인 사원이 입사 후 3년 6개월이 되는 날 퇴사한다. 이 사원의 이름과 입사일, 퇴사일을 출력 

SELECT first_name, hire_date, add_months(hire_date, 12*3 + 6) RETIRE_DATE FROM employees
WHERE employee_id = 120;

--오늘을 기준으로 가장 빨리 돌아오는 월요일을 출력

/* 일 : 1, 월:2, 화:3 ... 토:7 */
SELECT SYSDATE, next_day(sysdate,2) FROM dual;

4) to_char() : 원하는 형식으로 날짜 포멧을 변경하는 함수

    yyyy,yy : 연도  /  mm : 월  /  dd : 일 / month,mon : 월  / day : 요일 / scc : 세기 / HH:시간 / MS :분 / SS:초

SELECT to_char(sysdate,'yyyy/mm/dd') from dual;
SELECT to_char(sysdate,'yy/mm/dd') from dual;
SELECT to_char(sysdate, 'yyyy,mm,dd, month') from dual; 
SELECT to_char(sysdate, 'yyyy,mm,dd, mon') from dual;
SELECT to_char(sysdate, 'yyyy,mm,dd, day') from dual;
SELECT to_char(sysdate, 'scc yyyy-mm-dd') from dual;
/*기본 12시간 기준*/
SELECT to_char(sysdate, 'mm-dd HH') from dual; 
/*HH24 : 24시간 기준*/
SELECT to_char(sysdate, 'mm-dd HH24') from dual; 
/*MI : SS 분 초*/
SELECT to_char(sysdate, 'mm-dd HH24:MI:SS') from dual;

 


5. 기타 함수

1) NVL() : NULL값을 다른 데이터로 변경

2) DECODE() : SWITCH문의 역할을 하는 함수

3) CASE() : else if문의 역할을 하는 함수 

더보기

1) NVL() : NULL값을 다른 데이터로 변경

--사원 테이블에서 사번, 이름, 보너스를 출력

SELECT employee_id, first_name, NVL(commission_pct,0)*salary
FROM employees;
NVL 넣기 전
NVL넣은 후

2) DECODE() : SWITCH문의 역할을 하는 함수

 

SELECT department_id, DECODE(department_id,
		            	20, '마케팅',
                                    60, '전산',
                                    90, '경영',
                                    '기타부서')
FROM employees
ORDER BY department_id;

-- 부서테이블에서 manager_id가 null인경우 'x'로 변경하여 부서번호, 상사번호를 출력 ( 상사번호가 있다면 그대로 출력)

SELECT department_id, DECODE(manager_id, NULL, 'X',  manager_id ) FROM departments;

-- 이름과 직종을 출력하되 직종이 'IT_FROG'인 사람들은 개발자, 직종이 'SA_MAN'인 사원들은 '영업', 그렇지 않은 나머지 직종들은 '기타'라고 출력

SELECT first_name, DECODE(job_id ,'IT_FROG', '개발자','SA_MAN','영업', '기타'  ) FROM employees ;

3) CASE() : else if문의 역할을 하는 함수 

 

case when 조건식 then 컬럼값

when 조건식2 then 컬럼값

else 조건이 일치하지 않을때의 컬럼값

end 컬럼명

SELECT first_name, department_id, 
CASE WHEN department_id = 20 THEN'마케팅'
WHEN department_id = 60 THEN '전산실'
WHEN department_id = 90 THEN '경리부'
ELSE '기타부서'
END dept
FROM employees;

 

-- 회사에서 입사일에 따라 퇴직금을 차등 지급하려고 한다

이름, 입사일, 급여, 퇴직금 순으로 출력

(04년도 이전에 입사한 사원 : 급여*100, 04~ 06년도에 입사한 사원 : 급여 *50, 07이후에 입사한 직원 : 급여 *20)

SELECT first_name, hire_date, salary, 
CASE WHEN hire_date < '01/01/2004' THEN salary * 100
WHEN hire_date <'01/01/2007' THEN salary * 50
ELSE salary * 20
END SERVERANCE_PAY
FROM employees
ORDER BY hire_date;