SELECT SYSDATE FROM DUAL;
SELECT SYSTIMESTAMP FROM DUAL;
-- TIMESTAMP : 특정 시간을 나타내거나 기록하기 위한 문자열
SELECT ROUND( MONTHS_BETWEEN(SYSDATE, '2023-07-10') , 3) "수강 기간(개월)"
FROM DUAL;
-- 소수점 3째 자리까지 나타냄
-- EMPLOYEE 테이블에서 사원의 이름, 입사일, 근무한 개월 수, 근무 년차 조회
SELECT EMP_NAME, HIRE_DATE,
CEIL(MONTHS_BETWEEN(SYSDATE, HIRE_DATE)) "근무한 개월 수",
CEIL(MONTHS_BETWEEN(SYSDATE, HIRE_DATE) / 12 ) || '년차' "근무 년차"
FROM EMPLOYEE;
SELECT ADD_MONTHS(SYSDATE, 4) FROM DUAL;
SELECT ADD_MONTHS(SYSDATE, -1) FROM DUAL;
SELECT LAST_DAY('2024-02-01') FROM DUAL;
SELECT EMP_NAME,
EXTRACT(YEAR FROM HIRE_DATE) || '년' ||
EXTRACT(MONTH FROM HIRE_DATE) || '월' ||
EXTRACT(DAY FROM HIRE_DATE) || '일' AS 입사일
FROM EMPLOYEE;
: 문자열(CHAR), 숫자(NUMBER), 날짜(DATE) 끼리 형변환 가능
: TO_CHAR(날짜, [포맷]) : 날짜형 데이터를 문자형 데이터로 변경
: TO_CHAR(숫자, [포맷]) : 숫자형 데이터를 문자형 데이터로 변경
SELECT TO_CHAR(1234, '99999') FROM DUAL; -- ' 1234'
SELECT TO_CHAR(1234, '00000') FROM DUAL; -- '01234'
SELECT TO_CHAR(1000000, 'L9,999,999') FROM DUAL; -- ₩1,000,000
SELECT TO_CHAR(1000000, '$9,999,999') FROM DUAL;
-- 2023-01-10 10:21:00 화요일
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS DAY') FROM DUAL;
-- 2023년 01월 10일 (화)
SELECT TO_CHAR(SYSDATE, 'YYYY"년" MM"월" DD"일" (DY)') FROM DUAL;
TO_DATE(문자형 데이터, [포맷]) : 문자형 데이터를 날짜로 변환
TO_DATE(숫자형 데이터, [포맷]) : 숫자형 데이터를 날짜로 변환
SELECT TO_DATE('2023-01-10')FROM DUAL; -- DATE 타입으로 변환
SELECT TO_DATE(20230110) FROM DUAL; -- DATE 타입으로 변환
SELECT TO_DATE('510505', 'YYMMDD') FROM DUAL; --2051-05-05
SELECT TO_DATE('510505', 'RRMMDD') FROM DUAL; --1951-05-05 과거를 따짐
-- Y 패턴 : 현재 세기(21세기 == 20XX년 == 2000년대)
-- R 패턴 : 1세기를 기준으로 절반(50년) 이상인 경우 이전세기 (1900년대)
-- 절반(50년) 미만인 경우 현재 세기(2000년대)
-- EMPLOYEE 테이블에서 각 직원 태어난 생년월일 (1990년 05월 13일) 조회(별칭 생년월일)
SELECT EMP_NAME,
TO_CHAR(TO_DATE ( SUBSTR( EMP_NO, 1, INSTR(EMP_NO, '-') -1), 'RRMMDD'),
'YYYY"년" MM"월" DD"일"') AS 생년월일-- TO_DATE로 감싸기 전엔 문자열
FROM EMPLOYEE;
SELECT '1,000,000' + 500000 FROM DUAL;
-- SQL Error [1722][42000]: ORA-01722: 수치가 부적합합니다
SELECT TO_NUMBER('1,000,000', '9,999,999') + 5000000 FROM DUAL;
NULL과 산술 연산을 진행하면 결과는 무조건 NULL
SELECT EMP_NAME, SALARY, NVL(BONUS, 0), SALARY * NVL(BONUS, 0)
FROM EMPLOYEE; -- 보너스가 NULL인자리 다 0값으로 변함
EMPLOYEE테이블에서 보너스를 받으면 'O' ,안받으면 'X' 조회
SELECT EMP_NAME, BONUS, NVL2(BONUS, 'O', 'X') FROM EMPLOYEE;
: 여러가지 경우에 따라 알맞은 결과를 선택 할 수 있음
: 비교하고자 하는 값 또는 컬럼이 조건식과 같으면 결과값 반환
: 일치하는 값을 확인(자바의 SWITCH와 비슷함)
직원의 성별 구하기(남:1 / 여:2)
SELECT EMP_NAME, EMP_NO,
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;
: 비교하고자 하는 값 또는 컬럼이 조건식과 같으면 결과값 반환
: 조건은 범위 값 가능
-- EMPLOYEE테이블에서 급여가 500만원 이상이면 '대',
급여가 300만원 이상 500만 미만 이면 '중', 급여가 300만원 미만이면 '소'로 조회SELECT EMP_NAME, SALARY,
CASE
WHEN SALARY >= 5000000 THEN '대'
WHEN SALARY >= 3000000 THEN '중'
ELSE '소'
END "급여 받는 정도"
FROM EMPLOYEE;
: 하나 이상의 행을 그룹으로 묶어 연산하여 총합, 평균 등의 하나의 결과 행으로 반환하는 함수
-- 모든 직원의 급여 합
SELECT SUM(SALARY) FROM EMPLOYEE;
SELECT ROUND( AVG(SALARY) ) FROM EMPLOYEE;
-- 부서 코드가 'D9'인 사원들의 급여 합, 평균
SELECT SUM(SALARY), ROUND(AVG(SALARY)) --3
FROM EMPLOYEE -- 1
WHERE DEPT_CODE = 'D9'; --2
-- 해석 순서
--> 타입 제한 없음 ( 숫자 : 대/소, 날짜 : 과거/미래 , 문자열 : 문자 순서 )
-- 급여 최소값, 가장빠른 입사일, 알파벳순서가 가장빠른 이메일
SELECT MIN(SALARY), MIN(HIRE_DATE), MIN(EMAIL)
FROM EMPLOYEE;반대는 MAX(SALARY), MAX(HIRE_DATE), MAX(EMAIL)
-- EMPLOYEE 테이블에서 급여를 가장 많이 받는 사원의
-- 이름, 급여, 직급 코드 조회
SELECT EMP_NAME, SALARY, JOB_CODE
FROM EMPLOYEE
WHERE SALARY = ( SELECT MAX(SALARY) FROM EMPLOYEE );
-- 서브쿼리 + 그룹함수
-- EMPLOYEE 테이블의 행의 갯수
SELECT COUNT(*) FROM EMPLOYEE;
-- BONUS를 받는 사원 수
SELECT COUNT(BONUS) FROM EMPLOYEE; -- 9
SELECT COUNT(*) FROM EMPLOYEE
WHERE BONUS IS NOT NULL; -- 9
--> 좋은 방법은 아닌데 이런 방법도 있다
-- EMPLOYEE 테이블에서 성별이 남성인 사원의 수 조회
SELECT COUNT(*)
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO, 8, 1) = '1';