TIL(2023.08.07)

JAKE·2023년 8월 7일

TIL

목록 보기
20/48
post-thumbnail

🏃‍♂️What I learned

1. 함수 (두번째)

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;

2. GROUP BY

: 같은 값들이 여러개 기록된 컬럼을 가지고, 같은 값들을 하나로 묶음

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;

0개의 댓글