1) 형변환 함수
: 문자열(CHAR), 숫자(NUMBER), 날짜(DATE)끼리 형변환 가능
// 문자열로 변환
// TO_CHAR(날짜, [포맷]) : 날짜형 데이터를 문자형 데이터로 변경
// TO_CHAR(숫자, [포맷]) : 숫자형 데이터를 문자형 데이터로 변경
SELECT TO_CHAR(HIRE_DATE) FROM EMPLOYEE;
// 숫자 변환시 [포맷] 패턴
// 9 : 숫자 한칸을 의미, 여러개 작성 시 오른쪽 정렬
// 0 : 숫자 한칸을 의미, 여러개 작성 시 오른쪽 정렬 + 빈칸에 0 추가
// L : 현재 DB에 설정된 나라의 화폐 기호
SELECT TO_CHAR(1234, '99999999') FROM DUAL; -- ' 1234'
SELECT TO_CHAR(1234, '00000000') FROM DUAL; -- '00001234'
SELECT TO_CHAR(1000000, '9,999,999') || '원' FROM DUAL; -- '01234'
SELECT TO_CHAR(1000000, 'L9,999,999') || '원' FROM DUAL; -- '\1,000,000원'
// 날자 편환시 포맷 패턴
// YYYY : 년도 // YY: 년도(짧게);
// MM : 월
// DD : 일
// AM 또는 PM : 오전/오후 표시
// HH : 시간 / HH24 : 24시간 표기법
// MI 분 / SS: 초
// DAY : 요일(전체 '수요일') / DY : 요일(요일명만 '수')
SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD HH24:MI:SS DAY')FROM DUAL;
// 08/04(금)
SELECT TO_CHAR(SYSDATE, 'MM/DD (DY)') FROM DUAL;
//2024년 08월 04일 (금)
SELECT TO_CHAR(SYSDATE, 'YY" DD"일" (DY)') 날짜 FROM DUAL;
2) 날짜로 변환 TO_DATE
// TO_DATE(문자형 데이터, [포맷]) : 문자형 데이터를 날짜로 변경
// TO_DATE(숫자형 데이터, [포맷]) : 숫자형 데이터를 날짜로 변경
SELECT TO_DATE('2022-09-02')FROM DUAL; -- DATE 타입으로 변환
SELECT TO_DATE('20231230')FROM DUAL;
SELECT TO_DATE('230803 101835', 'YYMMDD HH24MISS')FROM DUAL;
//패턴을 적용해서 작성된 문자열의 각 문자가 어떤 형식인지 인지 시킴[포맷]으로
// Y 패턴은 21세기 패턴 (20--년) 현재 세기
// R 패턴 : 이전 세기
SELECT EMP_NAME, TO_CHAR(TO_DATE(SUBSTR(EMP_NO, 1, 6),'RRMMDD' ),
'YYYY"년" MM"월" DD"일"') 생년월일 FROM EMPLOYEE;
3) 숫자 형변환
// TO_NUMBER(문자 데이터, [포맷]) : 문자형 데이터를 숫자형으로 변경
SELECT '1,000,000' + 500000 FROM DUAL; -- X
SELECT TO_NUMBER('1,000,000', '9,999,999') + 500000 FROM DUAL;
4) NULL처리 함수
// NULL과 산술 진행 -> 결과는 NULL
// NVL(컬럼명, 컬럼값이 NULL일때 바꿀 값) : NULL인 컬럼값을 다른값으로 변경
SELECT EMP_NAME, SALARY, NVL(BONUS, 0), SALARY*NVL(BONUS, 0) FROM EMPLOYEE;
// NVL2(컬럼명, 바꿀값1, 바꿀값2) : 해당 컬럼에 값이 있으면 1, NULL이면 2
//EMPLOYEE에서 보너스 받으면 0 아니면 X
SELECT EMP_NAME, NVL2(BONUS, 'O', 'X') "보너스 수령" FROM EMPLOYEE;
5) 선택 함수 : 여러가지 경우에 따라 알맞은 결과를 선택할 수 있음
① DECODE
(계산식 | 컬럼명, 조건값1, 선택값1, 조건값2, 선택값2 ...., 아무것도 일치하지 않을 때)
// 비교하고자 하는 값 또는 컬럼이 조건식과 같으면 결과값 반환(자바의 SWITCH 비슷)
// 직원의 성별 구하기(남이면 1, 여면 2)
SELECT EMP_NAME,
DECODE(SUBSTR(EMP_NO, 8, 1), '1', '남성', '2', '여성') 성별 FROM EMPLOYEE;
//직원의 급여 인상하고자한다. 직급코드 J7은 20, J6은 15, J5는 10, 그외는 5
SELECT EMP_NAME, JOB_CODE, SALARY,
DECODE(JOB_CODE, 'J7', '20%', 'J6', '15%', 'J5', '10%', '5%') "인상율"
DECODE(JOB_CODE, 'J7', SALARY*1.2, 'J6', SALARY*1.15, 'J5',
SALARY*1.1, SALARY*1.05) "인상 급여"
FROM EMPLOYEE;
② CASE WHEN 조건식 THEN 결과
WHEN 조건식 THEN 결과
ELSE 결과값
END
// 비교하고자 하는 값 또는 컬럼이 조건식과 같으면 결과 값 반환
// 조건은 범위 값 가능
// EMPLOYEE 테이블에서
// 급여가 500 이상 대
// 급여가 300이상 500미만 중
// 급여가 300미만 소
SELECT EMP_NAME, SALARY,
CASE
WHEN SALARY >= 5000000 THEN '대'
WHEN SALARY >= 3000000 THEN '중'
ELSE '소'
END "급여 받는 정도"
FROM EMPLOYEE;
6) 그룹 함수
: 하나 이상의 행을 그룹으로 묶어 연산하여 총합, 평균 등의 하나의 결과 행으로 반환하는 함수
① SUM(숫자가 기록된 컬럼명) : 합계
// 모든 직원의 급여 합
SELECT SUM(SALARY) FROM EMPLOYEE;
② AVG(숫자가 기록된 컬럼명) : 평균
// 전 직원의 급여 평균
SELECT ROUND(AVG(SALARY)) FROM EMPLOYEE;
//부서코드가 D9인 사원의 급여합과 평균
SELECT SUM(SALARY), ROUND(AVG(SALARY))
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9';
③ MIN(컬럼명) : 최소값
④ MAX(컬럼명) : 최대값
타입 제한 없음(숫자: 대/소 || 날짜 : 과거/미래 || 문자 : 문자순서)
// 급여 최소값, 가장 빠른 입사일, 알파벳 순서가 가짱 빠른 이메일
SELECT MIN(SALARY), MIN(HIRE_DATE), MIN(EMAIL) FROM EMPLOYEE;
// 급여 최소값, 가장 빠른 입사일, 알파벳 순서가 가짱 빠른 이메일
SELECT MAX(SALARY), MAX(HIRE_DATE), MAX(EMAIL) FROM EMPLOYEE;
// 급여를 가장 많이 받는 사원의 이름 급여 직급 코드
SELECT EMP_NAME, SALARY, DEPT_CODE
FROM EMPLOYEE
WHERE SALARY = (SELECT MAX(SALARY)FROM EMPLOYEE); -- SUBQUERY + 그룹함수
7) COUNT(* | 컬럼명) : 행 개수를 헤아려서 리턴,
COUNT([DISTINCT] 컬럼명) : 중복을 제거
SELECT COUNT(DISTINCT DEPT_CODE) FROM EMPLOYEE; -- (NULL값 미포함)
// COUNT(*) : NULL을 포함한 전체 행 개수를 리턴
SELECT COUNT(*) FROM EMPLOYEE;
// COUNT(컬럼명) : NULL을 제외한 실제 값이 기록된 행 개수를 리턴
SELECT COUNT(BONUS) FROM EMPLOYEE;
SELECT COUNT(*) FROM EMPLOYEE WHERE BONUS IS NOT NULL;
//EMPLOYEE 테이블에서 남성인 사원의 수 조회
SELECT COUNT(*)
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO, 8, 1) = 1;
: 같은 값들이 여러개 기록된 컬럼을 가지고, 같은 값들을 하나로 묶음
1) GROUP BY 컬럼명 | 함수식
// 여러개의 값을 묶어서 하나로 처리할 목적으로 사용
// 그룹으로 묶은 값에 대해서는 SELECT절 그룹함수 사용
// 그룹 함수는 단 한개의 결과값만 산출
// 즉, 그룹이 여러개면 오류 발생
// EMPLOYEE 에서 부서코드, 부서별 급여 합 조회
SELECT SUM(SALARY) FROM EMPLOYEE;
SELECT DEPT_CODE,SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
// EMPLOYEE 에서 직급별 직급코드, 급여 평균, 인원수
SELECT JOB_CODE, ROUND(AVG(SALARY)), COUNT(*)
FROM EMPLOYEE
GROUP BY JOB_CODE
ORDER BY JOB_CODE;
//EMPLOYEE 테이블에서 성별(남여) 와 각 성별 별 인원수, 급여합을 인원수 오름차순으로 조회
SELECT DECODE(SUBSTR(EMP_NO, 8, 1), '1', '남','2','여') "성별",
COUNT(*) "인원수",
SUM(SALARY) "급여합"
FROM EMPLOYEE
GROUP BY DECODE(SUBSTR(EMP_NO, 8, 1), '1', '남','2','여')
ORDER BY 성별 DESC;
// WHERE 절 GROUP BY 절 혼합 : WHERE 절은 각 컬럼에 대한 조건
// EMPLOYEE 테이블에서 부서코드가 D5, D6인 부서의 평균 급여, 인원수 조회
SELECT ROUND(AVG(SALARY)) 평균급여, COUNT(*) 인원수
FROM EMPLOYEE
WHERE DEPT_CODE IN ('D5', 'D6')
GROUP BY DEPT_CODE ;
// EMPLOYEE에서 직급별 2000년도 이후 입사자들의 급여합을 조회
SELECT JOB_CODE 직급, SUM(SALARY) 급여합
FROM EMPLOYEE
WHERE TO_CHAR(HIRE_DATE, 'YYYY') >= 2000
GROUP BY JOB_CODE
ORDER BY JOB_CODE ;
// 여러 컬럼을 묶어서 그룹으로 지정 가능 --> 그룹내 그룹
// EMPLOYEE 테이블에서 부서별로 같은 직급인 사원의 수를 조회
SELECT DEPT_CODE, JOB_CODE, COUNT(*)
FROM EMPLOYEE
GROUP BY DEPT_CODE, JOB_CODE
ORDER BY DEPT_CODE, JOB_CODE DESC;
// DEPT_CODE로 그룹을 나누고,
// 나눠진 그룹내에서 JOB_CODE로 또 그룹을 분류 -> 세분화
// ** GROUP BY 사용시 주의사항
// SELECT 문에 GROUP BY 절 사용할 경우
// SELECT 절에 명시한 조회하려는 컬럼 중
// 그룹 함수가 적용되지 않은 컬럼을
//모두 GROUP BY에 작성해야함
2) HAVING 절 : 그룹 함수로 구해올 그룹에 대한 조건을 설정할 떄 사용
: HAVING 컬럼명 | 함수식 비교연산자 비교값
// 부서별 평균 급여가 3백만원 이상인 부서를 조회
SELECT DEPT_CODE
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING AVG(SALARY) >= 3000000
ORDER BY DEPT_CODE;
// EMPLOYEE 테이블에서 직급별 인원수가 5명 이하인 직급코드, 인원수 조회
SELECT DEPT_CODE, COUNT(*)
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING COUNT(*) <= 5
ORDER BY DEPT_CODE;
3) 집계함수(ROLLUP, CUBE)
: 그룹별 산출 결과 값의 집계를 계산하는 함 (그룹별로 중간 집계 결과를 추가)
// GROUP BY 절에서만 사용할 수 있는 함수
// ROLLUP(소계) : GROUP BY 절에서 가장 먼저 작성된 컬럼의 중간 집계를 처리하는 함수
SELECT DEPT_CODE, JOB_CODE, COUNT(*)
FROM EMPLOYEE
GROUP BY ROLLUP(DEPT_CODE, JOB_CODE)
ORDER BY 1;
// CUBE : GROUP BY 에서 작성된 모든 컬럼의 중간 집계를 처리하는 함수
SELECT DEPT_CODE, JOB_CODE, COUNT(*)
FROM EMPLOYEE
GROUP BY CUBE(DEPT_CODE, JOB_CODE)
ORDER BY 1;
4) 집합 연산자
: 여러 SELECT의 결과를 하나의 결과로 만드는 연산자
// UNION(합집합) : 두 SELECT의 결과를 하나로 합침, 단 중복은 한번만 작성
// INTERSECT(교집합) : 두 SELECT의 결과 중 중복되는 부분만 조회
// UNION ALL : UNION + INTERSECT : 합집합에서 중복제거하지 않음
// MINUS(차집합) : A에서 A,B 교집합을 제거하고 조회
// 부서코드가 D5인 사원의 사번, 이름 부서코드, 급여 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5'
UNION
//급여가 300만원 초과인 사원의 사번, 이름, 부서코드 급여 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE SALARY > 3000000;
// (주의사항)
// 집합연산자를 사용하기 위한 SELECT 문들은
// 조회하는 컬럼의 타입, 개수가 모두 동일해야 한다.
SELECT EMP_ID, EMP_NAME FROM EMPLOYEE;
UNION
SELECT DEPT_CODE, DEPT_TITLE FROM DEPARTMENT;