728x90

 

ALTER, DROP - 컬럼 추가,삭제,수정, 컬럼명 변경, 제약조건 추가 ,삭제, 제약조견명 변경

테이블명 변경, 삭제

RENAME A TO B

ADD

MODIFY

 

/*
------------------------------------------------------------------------------
----------------------------------ALTER --------------------------------------
------------------------------------------------------------------------------

-- ALTER 
객체 수정

컬럼 추가/삭제, 제약조건 추가/삭제, 컬럼 자료형 변경, 디폴트값 변경
테이블명/컬럼명/제약조건명 변경


*/

-- 컬럼 추가/삭제/수정

SELECT * FROM UC;

-- 추가
ALTER TABLE UC ADD (PHONE NUMBER);
ALTER TABLE UC ADD (NATIONALITY VARCHAR2(20) DEFAULT '한국');
-- 컬럼 PHONE, NATIONALITY 추가완료. NATIONALITY 지정안하면 기본값으로 한국


DESC UC;
-- 수정
ALTER TABLE UC
MODIFY USER_ID VARCHAR2(30)
MODIFY GENDER CHAR(3) -- ERROR : ORA-01441: cannot decrease column length because some value is too big
MODIFY NATIONALITY DEFAULT '미국';  -- 바꿀 자료형의 크기가 들어있는 데이터보다 작으면 에러

-- 삭제
ALTER TABLE UC
DROP COLUMN PHONE; -- PHONE 컬럼 삭제


-- 제약 조건과 함께 컬럼 삭제
ALTER TABLE UC
DROP COLUMN USER_NAME CASCADE CONSTRAINT;

DESC UC;

------------------------------------------------------------------------------
------------------------------------------------------------------------------

ALTER TABLE TB1
DROP COLUMN COL1;


-- 제약 조건과 함께 삭제
ALTER TABLE TB1
DROP COLUMN PK1 CASCADE CONSTRAINTS;

SELECT * FROM UC;

-- 제약 조건 추가
ALTER TABLE UC ADD CONSTRAINT UC_GEN_UQ UNIQUE(GENDER);
ALTER TABLE UC ADD CONSTRAINT EMP_ENAME_UQ UNIQUE(USER_NO);
ALTER TABLE UC ADD CONSTRAINT EMP_ENAME_UQ UNIQUE(USER_NO);



-- 제약조건 삭제
ALTER TABLE UC DROP CONSTRAINT EMP_ENAME_UQ;

-- 제약조건 한번에 여러개 삭제
ALTER TABLE UC
DROP CONSTRAINT SYS_C007129
DROP CONSTRAINT SYS_C007130
DROP CONSTRAINT SYS_C007127; -- GENDER의 CHECK 남여조건 빼고 제약조건 다 삭제

-- 컬럼명 변경
-- RENAME A TO B : A를 B로 컬럼명 변경
ALTER TABLE UC
RENAME COLUMN GENDER TO GENDER2;
ALTER TABLE UC
RENAME COLUMN GENDER2 TO GENDER;

-- 제약조건 이름 변경
ALTER TABLE UC
RENAME CONSTRAINT SYS_C007128 TO UC_CHECK1; 

DESC UC;
------------------------------------------------------------------------------

--테이블명 변경
ALTER TABLE DEPT_COPY
RENAME TO DEPT_COPY2;

--테이블 삭제
DROP TABLE DEPT_COPY;
--테이블+제약조건 삭제
DROP TABLE DEPT_COPY
CASCADE CONSTRAINTS;
728x90
반응형
728x90

 

JOIN 

INNER JOIN, OUTER JOIN

오라클 전용구문, ANSI 표준구문

-- 04.JOIN ★★★

/*
JOIN이란?
하나 이상의 테이블에서 데이터를 조회하기 위해 사용
여러개의 테이블들을 연결하여 데이터를 조회


<JOIN 세부 종류>
1.내부 조인
데이터가 ‘같은 부분’끼리 연결
위의 특성 때문에 해당하지 않는 데이터는 제외하고 반환됨
    1)오라클 전용구문 
        FROM절에 해당 테이블 모두 기술
        테이블끼리 연결하는 부분은 WHERE을 통해 연결
    2)ANSI 표준구문
        FROM절에 해당되는 테이블 모두 기술
        JOIN 구문 이용 
            JOIN + ON : 두 데이터값이 다른 이름일 때
            JOIN + USING : 두 데이터값이 같은 이름일 때
            but, 이름이 같더라도 JOIN + ON 사용가능

2.외부 조인
데이터가 같지 않은 행도 조인에 포함
내부 조인의 공통 데이터만 추출하는 특성에서 한쪽만 충족하는 데이터를 더 가져 올 수 있게 한 조인
    1)오라클 전용구문
        맞춰주는 테이블(기준이 아닌 테이블)의 컬럼 쪽에 (+)
    2)ANSI 표준구문 : 좀 더 LEFT, RIGHT 직관적
        LEFT OUTER JOIN
        RIGHT OUTER JOIN
        FULL OUTER JOIN : 양쪽 다 기준
        (OUTER)는 생략 가능


*/

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

--1.내부조인(Inner join)
--    1)오라클 전용 구문
--          컬럼명이 같으면 어느 테이블 컬럼인지 지정해줘야함 : 테이블명.컬럼명으로 지정
--    2)ANSI 표준 구문
--          내가 연결할 컬럼의 이름이 다를 때 = ON 사용
--          내가 연결할 컬럼이 이름이 같을 때 = USING 사용
--               컬럼 이름이 같다고 해서 무조건 USING 사용? X  


-- 사번, 이름, 부서코드, 부서명
-- 오라클 전용 구문
SELECT EMP_ID, EMP_NAME, DEPT_ID, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID -- 결과값 21개. 부서코드가 NULL인 직원은 제외
ORDER BY DEPT_ID;         

-- ANSI 표준 구문
SELECT EMP_ID, EMP_NAME, DEPT_ID, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);


-- 사번, 사원명, 직급코드, 직급명 // 각 사원에 대한 직급명 조회
-- 오라클 전용 구문
-- ANSI 표준 구문
-- 풀이과정
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE "E", JOB "J"
WHERE E.JOB_CODE = J.JOB_CODE; -- 23행
-- JOIN ~ ON
SELECT EMP_ID, EMP_NAME, EMPLOYEE.JOB_CODE, JOB_NAME
FROM EMPLOYEE
    JOIN JOB ON(EMPLOYEE.JOB_CODE = JOB.JOB_CODE);
SELECT EMP_ID, EMP_NAME, EMPLOYEE.JOB_CODE, JOB.JOB_NAME
FROM EMPLOYEE
    JOIN JOB ON(EMPLOYEE.JOB_CODE = JOB.JOB_CODE);
-- JOIN ~ USING
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
    JOIN JOB USING(JOB_CODE); 
-- USING 쓰면 FROM EMPLOYEE테이블에 JOB테이블을 조인시키면서 명시되므로,
-- USUNG()안에 JOB.이라고 명시할 필요X
    
-- < ANSI 표준 구문>
-- 내가 연결할 컬럼의 이름이 다를 때 = ON 사용
-- 내가 연결할 컬럼이 이름이 같을 때 = USING 사용
--      컬럼 이름이 같다고 해서 무조건 USING 사용? X  

-- 테이블명 EMPLOYEE에 별칭 사용 연결
-- 오라클 전용구문
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE "E", JOB "J"
WHERE E.JOB_CODE = J.JOB_CODE; -- 23행
-- ANSI 표준 구문
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE "E"
    JOIN JOB "J" ON(E.JOB_CODE = J.JOB_CODE); -- 23행


-- 부서명과 해당 부서의 지역명 조회
-- 오라클 전용 구문
-- ANSI 표준 구문
SELECT D.DEPT_TITLE, L.LOCAL_NAME
FROM DEPARTMENT "D", LOCATION "L"
WHERE D.LOCATION_ID = L.LOCAL_CODE;
-- 오라클 전용 구문
-- 경로지정X & 별칭X
SELECT DEPT_TITLE, LOCAL_NAME
FROM DEPARTMENT, LOCATION
WHERE LOCATION_ID = LOCAL_CODE;  -- 9행 인사관리부	ASIA1
-- ANSI 표준 구문
SELECT DEPT_TITLE, LOCAL_NAME
FROM DEPARTMENT
    JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE); -- 9행 인사관리부	ASIA1


------------------------------------------------------------------------------
------------------------------------------------------------------------------
-----------------------------2.외부조인(Outer join)-----------------------------
------------------------------------------------------------------------------
/*
내부 조인의 한계
매칭이 안되는 값이 있으면 조인해서 가져올 수 없는 한계
-> 보완하는 것이 외부조인
내부조인 개념이 일치하는 것을 가져오는 것

 2.외부조인(Outer join)
 컬럼 값이 일치하지 않는 행도 조인에 포함시킴
 아우터 조인 무조건 명시해야함

종류
1.LEFT (OUTER) JOIN
2.RIGHT (OUTER) JOIN
3.FULL (OUTER) JOIN
    - 오라클 구문은 풀아우터 조인 사용불가
- (OUTER) : 생략가능
    

*/ 

-- INNER JOIN
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); 
    -- 21행 : DEPT_CODE가 NULL인 사람은 제외(매칭X)



SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); -- 21행 : DEPT_CODE가 NULL인 사람은 제외(매칭X)
    

--1.LEFT (OUTER) JOIN
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    LEFT OUTER JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID(+);


-- 내부조인과 차이
-- 내부조인에서는 부서코드가 NULL인 직원은 제외되고 21행 나왔지만
-- LEFT OUTER JOIN은 NULL인 직원 2명도 포함했기에 23행 출력
 
/* 
내 기준으로 왼쪽에 있는 얘를 기준으로 삼겠다
즉 EMPLOYEE가 기준
디파트가 임플한테 맞춰주는 것. 
그래서 오라클 전용구문에서 표기가 기준점이 되는 테이블이 아닌 조이하는 테이블(+) 붙임
ex)WHERE DEPT_CODE = DEPT_ID(+);


<강사쌤 설명>
--레프트 라이트 조인 기준으로 왼쪽이면 임플로이 오른쪽이면 디파트
--레프트는 임플이 기준이라 임플로이 전부를 출력함(23개행). 내부조인 하면 하동운,이오리 안나옴.
--임플이 기준이라 NULL값도 출력을 해줌
--디파트가 임플 맞춰줘야함->23개행이 나올 수 있도록 

<내가 한 이해>
레프트 라이트 조인 기준으로 왼쪽이면 임플로이 오른쪽이면 디파트
임플로이에는 EMP_NAME에서 사원명 가져오는데 이게 23명이고,
디파에서는 DEPT_TITLE에서 부서명 가져오는데 이건 21개. 부서배정이 아직인 2명이
NULL로 나오는데 임플 기준이라 23행 맞춰줘야하니 부서명이 없는 2명은 NULL로 표시

 
Q.EMPLOYEE안에 DEPT_CODE가 있으니까 DEPT_CODE안에 NULL이 있어도 일단 쓰고, 
  DEPARTMENT를 DEPT_CODE에 맞춰서 나온거죠,,?
A.YES

*/


 
 
--2.RIGHT (OUTER) JOIN
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID;

SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    RIGHT OUTER JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);

-- ★양쪽 테이블의 매칭된 데이터 + 가져오길 원하는 한쪽 집합의 데이터★

--3.FULL (OUTER) JOIN
-- 둘 다 기준이 된다
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID(+);
-- ERROR :  a predicate may reference only one outer-joined table
-- 오라클 구문으로는 기준을 하나만 정할 수 있어 풀아우터조인은 사용불가

SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    FULL OUTER JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); 
-- 26행 출력 : 
-- LEFT의 부서배정안된 22이오리23하동운 NULL 데이터 + RIGHT의 부서만 있고 직원 없는 
-- (NULL) 해외영업3부,마케팅부,국내영업부해서 
-- 내부조인 결과 21행에 LEFT 2행+ RIGHT 3행 = 21+2+3= 총26행
728x90
반응형
728x90

3.날짜 함수

SYSDATE

MONTHS_BETWEEN

ADD_MONTHS

NEXT_DAY

LAST_DAY

EXTRACT

 

4.형변환 함수

1)TO_CHAR()

2)TO_DATE()

3)TO_NUMBER()

 

5.NULL처리 함수

NVL

NVL2

NULLIF

 

6.선택함수

DECODE : 

CASE WHEN THEN

 

그룹함수

SUM,AVG,MIN/MAX,COUNT

-- 3)날짜 관련 함수

-- SYSDATE
-- 시스템에 저장되어있는 시간을 사용

SELECT SYSDATE FROM DUAL; -- 22/03/14



-- MONTHS_BETWEEN
-- ex) MONTHS_BETWEEN(SYSDATE, HIRE_DATE)
-- 개월수의 차를 숫자로 리턴해주는 함수
SELECT MONTHS_BETWEEN(SYSDATE, HIRE_DATE) FROM EMPLOYEE; -- 385일 차이
SELECT SYSDATE,HIRE_DATE, MONTHS_BETWEEN(SYSDATE, HIRE_DATE) FROM EMPLOYEE;
SELECT SYSDATE,HIRE_DATE, ABS(MONTHS_BETWEEN(SYSDATE, HIRE_DATE)) FROM EMPLOYEE;


-- EMPLOYEE테이블에서 사원의 이름, 입사일, 근무 개월 수 조회
SELECT EMP_NAME, HIRE_DATE, MONTHS_BETWEEN(SYSDATE,HIRE_DATE) "근무 개월 수"
FROM EMPLOYEE;

SELECT EMP_NAME, HIRE_DATE, CEIL(ABS(MONTHS_BETWEEN(HIRE_DATE, SYSDATE))) || '개월차'
FROM EMPLOYEE; -- 368개월차
-- 앞뒤로 뭐가 올지 모른다면 ABS를 넣어서 절대값으로 받아오면 된다

SELECT EMP_NAME, HIRE_DATE, CEIL(MONTHS_BETWEEN(SYSDATE,HIRE_DATE)) || '일수'"근무일수" FROM EMPLOYEE;




-- ADD_MONTHS
-- 기준 날짜에다 지정한 숫자만큼의 개월수로 더한 날짜 리턴
SELECT ADD_MONTHS(SYSDATE,4) FROM EMPLOYEE; -- 22/07/19
-- 지금부터 4개월 뒤 반환
SELECT ADD_MONTHS(SYSDATE,12) FROM EMPLOYEE; -- 23/03/19
-- 개월수가 더해져서 연도가 넘어가면 연도도 올라감

--EMPLOYEE테이블에서 사원의 이름, 입사일, 입사 후 6개월이 된 날짜 조회
SELECT EMP_NAME, HIRE_DATE, ADD_MONTHS(HIRE_DATE,6) FROM EMPLOYEE;
SELECT EMP_NAME, ADD_MONTHS('00/01/01',12) FROM EMPLOYEE; -- 01/01/01
-- 마이너스 -12개월
SELECT EMP_NAME, ADD_MONTHS('00/01/01',-12) FROM EMPLOYEE; -- 99/01/01



-- NEXT_DAY
-- 기준 날짜에서 구하려는 요일에 가장 가까운 날짜 리턴
-- 1=일, 2=월, 3=화,4=수, 5=목, 6=금, 7=토
-- 텍스트의 맨 앞글자만 따와서 요일 반환

SELECT SYSDATE, NEXT_DAY(SYSDATE, '일') FROM DUAL; -- 22/03/19	22/03/20
SELECT SYSDATE, NEXT_DAY(SYSDATE, '토') FROM DUAL; -- 22/03/19	22/03/26

-- 지금 기준으로부터 가장 가까운 목요일 구하기
SELECT NEXT_DAY(SYSDATE, '목') FROM DUAL;    -- 22/03/24
SELECT NEXT_DAY(SYSDATE, '목요일') FROM DUAL; -- 22/03/24
SELECT NEXT_DAY(SYSDATE, 5) FROM DUAL;       -- 22/03/24   
-- 1=일, 2=월, 3=화,4=수, 5=목, 6=금, 7=토
SELECT NEXT_DAY(SYSDATE, 'THUR') FROM DUAL; -- ERROR :  not a valid day of the week



SELECT SYSDATE, NEXT_DAY(SYSDATE, '목성주기') FROM DUAL; -- 22/03/19	22/03/24
-- 요일과 관련 없는 단어지만 맨 앞글자 '목'만 따서 요일 반환하는 걸 알 수 있다
SELECT SYSDATE, NEXT_DAY(SYSDATE, '금성') FROM DUAL; -- 22/03/19	22/03/25
-- 금성의 맨 앞글자 '금' = 금요일


-- 한글만 인지하게끔 설정이 되어있어 인식오류 뜨는 것

-- 영어로 세팅
ALTER SESSION SET NLS_LANGUAGE = AMERICAN; -- Session이(가) 변경되었습니다.
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THURSDAY') FROM DUAL; -- 22/03/15	22/03/17
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THUR') FROM DUAL; -- 22/03/15	22/03/17
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THURSTY') FROM DUAL; -- 22/03/15	22/03/17
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THUR--') FROM DUAL; -- 22/03/15	22/03/17
-- 한글과 동일하게 앞글자만 맞으면 요일 반환. 아마도 첫발음의 한글자를 치는 듯

SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THURDAY') FROM DUAL; -- 22/03/19	22/03/24
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THUR') FROM DUAL;    -- 22/03/19	22/03/24
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'THUR---') FROM DUAL;


-- 한글로 세팅
ALTER SESSION SET NLS_LANGUAGE = KOREAN; -- Session이(가) 변경되었습니다.

SELECT NEXT_DAY(SYSDATE, '금') FROM DUAL; -- 22/03/25
SELECT NEXT_DAY(SYSDATE, '금성') FROM DUAL;


-- LAST_DAY
-- 해당 날짜의 월의 마지막 일 반환
SELECT LAST_DAY(SYSDATE) FROM DUAL; -- 22/03/31
SELECT LAST_DAY(HIRE_DATE) FROM EMPLOYEE; -- 90/02/28 01/09/30
SELECT LAST_DAY(JOB_CODE) FROM EMPLOYEE; -- ERROR
-- ORA-01841: (full) year must be between -4713 and +9999, and not be 0


-- EXTRACT
-- 년, 월, 일 정보 추출 반환
-- 시간은 추출 불가

SELECT EXTRACT(SYSDATE-hire_date) FROM EMPLOYEE;

SELECT EXTRACT(YEAR FROM SYSDATE), EXTRACT(MONTH FROM SYSDATE),
       EXTRACT(DAY FROM SYSDATE) FROM EMPLOYEE; -- 2022	3	19
SELECT EXTRACT(DAY FROM SYSDATE)
--        EXTRACT(HOUR FROM SYSDATE),  -- 시간은 추출 불가
--        EXTRACT(MINUTE FROM SYSDATE) 
FROM EMPLOYEE;
       
-- EMPLOYEE테이블에서 사원의 이름, 입사연도, 입사월, 입사일 조회

SELECT EMP_NAME, EXTRACT(YEAR FROM HIRE_DATE) 입사연도,
                 EXTRACT(MONTH FROM HIRE_DATE) 입사월, 
                 EXTRACT(MONTH FROM HIRE_DATE) 입사일
FROM EMPLOYEE; -- 선동일	1990	2	2


-- EMPLOYEE테이블에서 사원의 이름, 입사일, 근무년수 조회
-- 단, 근무년수는 현재연도 - 입사연도로 조회
SELECT EMP_NAME,HIRE_DATE, SYSDATE,
        EXTRACT(YEAR FROM SYSDATE) - EXTRACT(YEAR FROM HIRE_DATE) 근무년수
FROM EMPLOYEE; -- 선동일	90/02/06	22/03/19	32





----------실습문제------------
--1.EMPLOYEE테이블에서 사원명, 입사일-오늘, 오늘-입사일 조회
-- 단, 별칭은 근무일수1, 근무일수2로 하고 모두 정수처리(내림)와 양수로 처리
--2.EMPLOYEE테이블에서 사번이 홀수인 직원들의 정보 모두 조회
--3.EMPLOYEE테이블에서 근무년수가 20년 이상인 직원 전체 정보 조회
--4.EMPLOYEE테이블에서 사원명, 입사일, 입사한 달의 근무일수 조회


--1.EMPLOYEE테이블에서 사원명, 입사일-오늘, 오늘-입사일 조회
-- 단, 별칭은 근무일수1, 근무일수2로 하고 모두 정수처리(내림)와 양수로 처리
-- 절삭이 아니라 내림이라 FLOOR. TRUNC는 절삭이고 FLOOR는 수학적 내림
SELECT EMP_NAME, FLOOR(ABS(HIRE_DATE - SYSDATE)) 근무일수1, 
                FLOOR(ABS(SYSDATE - HIRE_DATE)) 근무일수2
FROM EMPLOYEE;

SELECT EMP_NAME, ABS(FLOOR(HIRE_DATE - SYSDATE)) 근무일수1, FLOOR(SYSDATE - HIRE_DATE) 근무일수2 
FROM EMPLOYEE;  

SELECT EMP_NAME, FLOOR(ABS(HIRE_DATE - SYSDATE)) 근무일수1, FLOOR(ABS(SYSDATE - HIRE_DATE)) 근무일수2 
FROM EMPLOYEE;  

--2.EMPLOYEE테이블에서 사번이 홀수인 직원들의 정보 모두 조회
-- 오라클에서는 % 나머지 연산지 지원X
SELECT *
FROM EMPLOYEE
WHERE MOD(EMP_ID,2) = 1;
--WHERE MOD(EMP_ID,2) != 0;

--3.EMPLOYEE테이블에서 근무년수가 20년 이상인 직원 전체 정보 조회
-- 방법1
SELECT *
FROM EMPLOYEE
WHERE CEIL(ABS(MONTHS_BETWEEN(SYSDATE, HIRE_DATE)))/12 >=20;

-- MONTHS_BETWEEN 반환값 확인방법
SELECT EMP_NAME, CEIL(ABS(MONTHS_BETWEEN(HIRE_DATE, SYSDATE)))
--SELECT EMP_NAME, ABS(MONTHS_BETWEEN(HIRE_DATE, SYSDATE))
FROM EMPLOYEE
WHERE CEIL(ABS(MONTHS_BETWEEN(SYSDATE ,HIRE_DATE))) >=20;

-- 방법2
SELECT *
FROM EMPLOYEE
WHERE ABS(MONTHS_BETWEEN(SYSDATE, HIRE_DATE))/12 >=20;

-- 방법3
SELECT * FROM EMPLOYEE
WHERE MONTHS_BETWEEN(SYSDATE, HIRE_DATE)>=240;
-- 방법4
SELECT *  FROM EMPLOYEE
WHERE (SYSDATE - HIRE_DATE) >= 365*20;
-- 방법5
SELECT *
FROM EMPLOYEE
WHERE ADD_MONTHS(HIRE_DATE,240) <= SYSDATE;
 
--4.EMPLOYEE테이블에서 사원명, 입사일, 입사한 달의 근무일수 조회
SELECT EMP_NAME 사원명, HIRE_DATE 입사일, 
    EXTRACT(DAY FROM LAST_DAY(HIRE_DATE))- EXTRACT(DAY FROM HIRE_DATE) "입사한 달의 근무일수"
FROM EMPLOYEE;

SELECT EMP_NAME, HIRE_DATE, LAST_DAY(HIRE_DATE) - HIRE_DATE
FROM EMPLOYEE;

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------



-- 4)형변환 함수
-- A) TO_CHAR
-- B) TO_DATE
-- C) TO_NUMBER

-- A) TO_CHAR : 날짜/숫자형 데이터를 문자형 데이터로 변경
-- B) TO_DATE : 문자/숫자형 데이터를 날짜형 데이터로 변환
-- C) TO_NUMBER : 문자형 데이터를 숫자형 데이터로 변환


-- A) TO_CHAR 
-- 날짜/숫자형 데이터를 문자형 데이터로 변경
-- 자릿수에 맞춰 문자로 형변환
-- TO_CHAR(형변환할 날짜or숫자OR컬럼명, 전체자릿수 0 OR 9)
--      여분공간을 0은 0으로 9는 공백으로
    -- 남은 공백은 왼쪽에 표시
SELECT 1234 LITERAL_NUMBER FROM DUAL; -- 1234
SELECT 12345 LITERAL_NUMBER FROM DUAL;
SELECT TO_CHAR(1234) FROM DUAL; -- 1234
SELECT TO_CHAR('1234') FROM DUAL; -- 문자to문자 형변환 가능
SELECT 1234 LITERAL_NUMBER , TO_CHAR(1234) FROM DUAL; -- 1234	1234
SELECT 1234 "   숫자   ", TO_CHAR(1234) "   문자   " FROM DUAL;
-- 숫자로 인지되었으면 오른쪽 정렬, 문자로 인지되어있으면 왼쪽 정렬
-- 글자가 어디에 들어가 있느냐에 따라서 문자인지 숫자인지 구분 가능

SELECT 369 + 963, TO_CHAR(369)+TO_CHAR(963) FROM DUAL; -- 1332
SELECT 1234+4321, TO_CHAR(1234)+TO_CHAR(4321) FROM DUAL; -- 5555	5555 
-- 문자인데 연산이 가능한 이유 : 숫자로 형변환에 문제 없는 문자는 오라클에서 자동으로 연산해줌
-- 문자 연산 가능 // 자바에선 불가능

SELECT TO_CHAR(2222, '999999') FROM DUAL;  --    2222//
SELECT TO_CHAR(2222, '000000') FROM DUAL;  --  002222//
SELECT TO_CHAR(2222, '111111') FROM DUAL;  --  ERROR:ORA-01481: invalid number format model
SELECT TO_CHAR(1234, '99999') FROM DUAL;   --  (공백)1234
SELECT TO_CHAR(1234, '99999') A FROM DUAL; --  (공백)1234
-- '99999'의 의미는 5칸을 만들겠다. 여기에 1234를 넣고 빈 공간은 공백으로 하겠다는 의미
-- ' ' 안에는 9와 0만 가능. 다른 숫자는 에러 
SELECT TO_CHAR(1234, '99') A FROM DUAL;    -- ###
SELECT TO_CHAR(1234, '88') A FROM DUAL;    -- ERROR
SELECT TO_CHAR(1234,'00000') A FROM DUAL;  -- 01234
-- 비어있는 곳을 0으로 채워라


SELECT TO_CHAR(1234,'$99999') FROM DUAL; --   $1234
SELECT TO_CHAR(1234,'L99999') FROM DUAL;     --         ₩1234
-- L을 붙인건 현재 설정된 나라의 원화표시를 붙인 것
SELECT TO_CHAR(1234,'FML99999') FROM DUAL;   -- ₩1234
-- FM을 추가로 넣으면 공백 없애는 것
SELECT TO_CHAR(1234,'$99999') FROM DUAL;     --   $1234
-- 달러를 찍고 싶으면 L대신 $기호
SELECT TO_CHAR(1234,'FM$99999') FROM DUAL;   --$1234
SELECT TO_CHAR(1234,'99,999') FROM DUAL;     --  1,234
SELECT TO_CHAR(1234,'FM99,999') FROM DUAL;   -- 1,234
SELECT TO_CHAR(1234,'00,000') FROM DUAL;     --  01,234
SELECT TO_CHAR(1234,'FM00,000') FROM DUAL;   -- 01,234
SELECT TO_CHAR(1234,'999') FROM DUAL; -- ####
-- 자릿수가 부족해서 ####으로 대체 출력

-- 1234보다 더 적은 자리수를 지정할 경우는?
-- ##을 이용하면 됨



-- EMPLOYEE테이블에서 사원명, 급여(\(원화표시)9,000,000 형식) 조회
-- 모범 답안
SELECT EMP_NAME, TO_CHAR(SALARY, 'L999,999,999')
--SELECT EMP_NAME, TO_CHAR(SALARY, 'FML999,999,999')
FROM EMPLOYEE;


SELECT EMP_NAME,TO_CHAR(SALARY,'L9,999,999')
FROM EMPLOYEE; --         ₩8,000,000
SELECT EMP_NAME,TO_CHAR(SALARY,'L999,999,999') 
FROM EMPLOYEE; --           ₩8,000,000
SELECT EMP_NAME,TO_CHAR(SALARY,'FML999,999,999') 
FROM EMPLOYEE; -- ₩8,000,000


-- 시간
SELECT TO_CHAR(SYSDATE, 'HH:MI:SS') FROM DUAL; -- 03:40:27
SELECT TO_CHAR(SYSDATE, 'AM:HH:MI:SS') FROM DUAL; -- 오후:03:41:01
SELECT TO_CHAR(SYSDATE, 'PM:HH:MI:SS') FROM DUAL; -- 오후:03:41:43
SELECT TO_CHAR(SYSDATE, 'AM:HH24:MI:SS') FROM DUAL; -- 오후:15:42:38
SELECT TO_CHAR(SYSDATE, 'HH24:MI:SS') FROM DUAL;    -- 15:43:02
-- 날짜
SELECT TO_CHAR(SYSDATE, 'YY-MM-DD') FROM DUAL;                  --22-03-20
SELECT TO_CHAR(SYSDATE, 'YY-MM-DD DAY') FROM DUAL;              -- 22-03-20 일요일
SELECT TO_CHAR(SYSDATE, 'YY-MM-DD DAY HH:MI:SS') FROM DUAL;     -- 22-03-20 일요일 03:46:52
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD DAY HH:MI:SS') FROM DUAL;   -- 2022-03-20 일요일 03:48:07
SELECT TO_CHAR(SYSDATE, 'YYYY-FMMM-DD DAY HH:MI:SS') FROM DUAL; --2022-3-20 일요일 3:48:47 공백제거
SELECT TO_CHAR(SYSDATE, 'YYYY-FMMM-DD DAY AM HH:MI:SS') FROM DUAL; -- 2022-3-20 일요일 오후 3:50:0
SELECT TO_CHAR(SYSDATE, 'YYYY"년"-MM"월"-DD"일" DAY') FROM DUAL; -- 2022년-03월-20일 일요일 // 리터럴 추가
SELECT TO_CHAR(SYSDATE, 'YYYY"년"-MM"월"-DD"일" DAY AM HH:MI:SS') FROM DUAL; -- 2022년-03월-20일 일요일 오후 03:55:31


SELECT TO_CHAR(SYSDATE) FROM DUAL;                  -- 22/03/15
SELECT TO_CHAR(SYSDATE, 'HH:MI:SS') FROM DUAL;      -- 08:07:45
SELECT TO_CHAR(SYSDATE, 'AM:HH:MI:SS') FROM DUAL;   -- 오후:08:08:07
SELECT TO_CHAR(SYSDATE, 'PM:HH:MI:SS') FROM DUAL;   -- 오후:08:08:07 // AM PM 아무거나 쓰면됨  
SELECT TO_CHAR(SYSDATE, 'AM:HH24:MI:SS') FROM DUAL; -- 오후:20:10:01
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD DAY AM HH:MI:SS') FROM DUAL;  --2022-03-15 화요일 오후 08:10:50
SELECT TO_CHAR(SYSDATE, 'YYYY-FMMM-DD DAY AM HH:MI:SS') FROM DUAL;--2022-3-15 화요일 오후 8:10:59
-- FM을 적용시키면 뒤에까지 적용되서 공백제거 되서 나온다
-- 01초가 나와야하는데 1초가 나옴
SELECT TO_CHAR(SYSDATE, 'YYYY"년"-MM"월"-DD"일" DAY AM HH:MI:SS') FROM DUAL; -- 2022년-03월-15일 화요일 오전 11:40:48
SELECT TO_CHAR(SYSDATE, 'YYYY"년" MM"월" DD"일" DAY AM HH:MI:SS') FROM DUAL; -- 2022년 03월 15일 화요일 오후 08:15:13
-- 글자 출력
-- 글자처럼 비어있는 자리를 지워주는 역할

-- 보이는게 다른 3가지
SELECT TO_CHAR(SYSDATE,'YYYY') FROM DUAL; -- 2022
SELECT TO_CHAR(SYSDATE,'YY') FROM DUAL; -- 22
SELECT TO_CHAR(SYSDATE,'YEAR')FROM DUAL; -- TWENTY TWENTY-TWO

SELECT TO_CHAR(SYSDATE,'MM')FROM DUAL; -- 03
SELECT TO_CHAR(SYSDATE,'MONTH')FROM DUAL; -- 3월 
SELECT TO_CHAR(SYSDATE,'MON')FROM DUAL; -- 3월 
SELECT TO_CHAR(SYSDATE,'RM')FROM DUAL; -- III 
SELECT TO_CHAR(SYSDATE,'MM'), TO_CHAR(SYSDATE,'MONTH'),
        TO_CHAR(SYSDATE,'MON'), TO_CHAR(SYSDATE,'RM')
FROM DUAL;  -- 03	3월 	3월 	III 


SELECT TO_CHAR(SYSDATE, 'YYYY') FROM DUAL;  -- 2022
SELECT TO_CHAR(SYSDATE, 'YY') FROM DUAL;    -- 22
SELECT TO_CHAR(SYSDATE, 'MM') FROM DUAL;    -- 03
SELECT TO_CHAR(SYSDATE, 'MONTH') FROM DUAL; -- 3월
SELECT TO_CHAR(SYSDATE, 'MON') FROM DUAL;   -- 3월
SELECT TO_CHAR(SYSDATE, 'RM') FROM DUAL;    -- III 
SELECT TO_CHAR(SYSDATE, 'YY-MONTH-RM') FROM DUAL; -- 22-3월 -III 
SELECT TO_CHAR(SYSDATE, 'YY MONTH RM') FROM DUAL; -- 22 3월  III 
SELECT TO_CHAR(SYSDATE, 'DDD'), -- 한 해를 기준으로 몇일이 지나있는가
       TO_CHAR(SYSDATE, 'DD'),  -- 한 달을 기준으로 몇일이 지나있는가
       TO_CHAR(SYSDATE, 'D')    -- 한 주를 기준으로 몇일이 지나있는가(일요일 기준)
FROM DUAL; -- 079	20	1
SELECT TO_CHAR(SYSDATE, 'Q'),   -- Q : 분기를 나타냄. 1-4분기
       TO_CHAR(SYSDATE, 'DAY'), -- DAY : 요일
       TO_CHAR(SYSDATE, 'DY')   -- DY : 요일
FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'Q DAY DDD') FROM DUAL; -- 1 일요일 079

SELECT TO_CHAR(SYSDATE,'DDD'), -- 한달을 기준으로 몇일이 지나있는가
    TO_CHAR(SYSDATE,'DD'), -- 주를 기준으로 몇일이 지나있는가
    TO_CHAR(SYSDATE,'D') -- 한 해를 기준으로 몇일이 지나있는가
FROM DUAL; -- 074	15	3
 
SELECT TO_CHAR(SYSDATE,'Q'), TO_CHAR(SYSDATE,'DAY'), TO_CHAR(SYSDATE,'DY')
FROM DUAL; -- 1	일요일	일
-- Q : 분기를 나타냄. 1-4분기
-- DAY : 요일
-- DY : 요일



--EMPLOYEE테이블에서 이름, 입사일(2022년 03월 15일 (화) 형식) 조회

SELECT EMP_NAME, TO_CHAR(HIRE_DATE, 'YYYY"년" MM"월" DD"일" (DY)') 
FROM EMPLOYEE; -- 선동일	1990년 02월 06일 (화)


FROM EMPLOYEE;



------------------------------------------------------------------------------
------------------------------------------------------------------------------




-- B) TO_DATE
-- 문자/숫자형 데이터를 날짜형 데이터로 변환
--
-- Y : 두자리 연도에 무조건 현재 세기(21세기 , 20XX) 적용
-- R : 두자리 연도가 50이상일 때, 이전 세기(20세기,19XX) 적용
--     두자리 연도가 50미만일 때, 현재 세기(21세기, 20XX) 적용



SELECT TO_DATE('20220315','YYYYMMDD') FROM DUAL; -- 22/03/15
SELECT TO_DATE(20220315,'YYYYMMDD') FROM DUAL; -- 22/03/15
SELECT TO_DATE('20220315','YYYYMMDD') FROM DUAL; -- 22/03/15

-- 입력 받은 문자열 : 20220713을 2022년 07월 13일 형식으로 출력하고 싶다면?
-- 20220713  -> 2022년 07월 13일
-- 문자열을 받는거니 TO_CHAR써서 하면 편하지 않을까? 해서 써보면 에러
-- TO_CHAR는 날짜/숫자형 데이터를 문자형 데이터로 변경하는 함수
-- 아래에서 TO_CHAR()의 첫 매개변수가 숫자가 ' '로 감싸진 문자라서 에러나는 것
-- 문자+문자 더하기 가능한건? EX)TO_CHAR(1234) + TO_CHAR(4321)
-- 문자가 숫자로 바뀌는 문자라면 문제없이 연산처리 가능하도록 오라클은 되어있기에 가능했던 것
-- 자바는 '1234'+'4321'이면 '12344321'이겠지만 오라클은 숫자형식인 문자면 자동형변환해서 연산해준다

SELECT TO_CHAR('20220315','YYYY"년" MM"월" DD"일"') --  ERROR : invalid number format model
FROM DUAL;
-- TO_CHAR()를 쓸려면 '20220315'의 형식 바꿔야함
-- TO_DATE()로 날짜 데이터를 만듬 : SELECT T0_DATE('20220315','YYYYMMDD')

SELECT TO_CHAR('20220315','YYYY"년" MM"월" DD"일"') 
FROM DUAL; --  ERROR : invalid number format model
SELECT TO_CHAR(TO_DATE('20220315','YYYYMMDD'), 'YYYY"년" MM"월" DD"일"')
FROM DUAL; -- 2022년 03월 15일


SELECT TO_CHAR(TO_DATE('220713 175019','YYMMDD HH24MISS'), 'YY-MM-DD AM HH:MI:SS DY')
FROM DUAL; -- 22-07-13 오후 05:50:19 수
-- 데이트는 시간까지 보여주지 않는다. 타임스탬프 써야함

-- TO_DATE()에서의 연도 표시 : YY, RR
-- 연도표시를 YY말고도 RR도 가능. 차이는?
SELECT TO_DATE('980630', 'YYMMDD'),  -- 98/06/30
        TO_DATE('980630', 'RRMMDD'), -- 98/06/30
        TO_DATE('140918', 'YYMMDD'), -- 14/09/18
        TO_DATE('140918', 'RRMMDD')  -- 14/09/18
FROM DUAL; -- 98/06/30	98/06/30	14/09/18	14/09/18
-- TO_DATE() 출력에서는 차이가 없어보인다. TO_CHAR()+TO_DATE()에서는?
SELECT TO_CHAR(TO_DATE('980630', 'YYMMDD'),'YYYYMMDD'),  -- 20980630
        TO_CHAR(TO_DATE('980630', 'RRMMDD'),'YYYYMMDD'), -- 19980630
        TO_CHAR(TO_DATE('140918', 'YYMMDD'),'YYYYMMDD'), -- 20140918
        TO_CHAR(TO_DATE('140918', 'RRMMDD'),'YYYYMMDD')  -- 20140918
FROM DUAL; -- 20980630	19980630	20140918	20140918
-- 앞에있는 천의자리랑 백의자리가 생략되어있어서 그동안 몰랐던 것.
-- TO_CHAR()로 천의자리까지 만들어준 것
-- Y : 두자리 연도에 무조건 현재 세기(21세기 , 20XX) 적용
-- R : 두자리 연도가 50이상일 때, 이전 세기(20세기,19XX) 적용
--     두자리 연도가 50미만일 때, 현재 세기(21세가, 20XX) 적용




-- 문자 -> 날짜
SELECT TO_DATE('20220320','YYYYMMDD') FROM DUAL; -- 22/03/20 
-- 숫자 -> 날짜
SELECT TO_DATE(20220320, 'YYYYMMDD') FROM DUAL;  -- 22/03/20

-- 데이트는 시간까지 보여주지 않는다. 타임스탬프 써야함
-- TO_DATE + TO_CHAR
-- 년,월,일,시간 같은 것들을 붙일려면 TO_CHAR로 감싼다
SELECT TO_CHAR(TO_DATE(20220320,'YYYYMMDD'), 'YYYY"년" MM"월" DD"일"')
FROM DUAL; -- 2022년 03월 20일
SELECT TO_DATE('220713 215005','YYMMDD HH24MISS')
FROM DUAL; -- 22/07/13 // 시간 출력 X
SELECT TO_CHAR(TO_DATE('220713 215005','YYMMDD HH24MISS'), 'YY/MM/DD AM HH:MI:SS DY')
FROM DUAL; -- 22/07/13 오후 09:50:05 수
SELECT TO_CHAR(TO_DATE('220713 175019','YYMMDD HH24MISS'), 'YY-MM-DD AM FMHH:MI:SS DY')
FROM DUAL; -- 22-07-13 오후 5:50:19 수


-- Y와 R의 차이
-- TO_DATE()로만으로는 차이가 없어보인다. TO_DATE()+TO_CHAR()는?
SELECT TO_DATE('000320','YYMMDD'), -- 00/03/20
       TO_DATE('000320','RRMMDD'), -- 00/03/20
       TO_DATE('450625','YYMMDD'), -- 45/06/25
       TO_DATE('450625','RRMMDD')  -- 45/06/25
FROM DUAL;
SELECT TO_CHAR(TO_DATE('900320','YYMMDD'),'YYYY/MM/DD'), -- 2090/03/20
       TO_CHAR(TO_DATE('900320','RRMMDD'),'YYYY/MM/DD'), -- 1990/03/20
       TO_CHAR(TO_DATE('450625','YYMMDD'),'YYYY/MM/DD'), -- 2045/06/25
       TO_CHAR(TO_DATE('450625','RRMMDD'),'YYYY/MM/DD')  -- 2045/06/25
FROM DUAL;

------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- C) TO_NUMBER
-- 문자형 데이터를 숫자형 데이터로 변환
-- TO_NUMBER(변환할 컬럼or문자,'들어온 데이터형식 인식시키는기준')
-- TO_NUMBER('10,000','999,999')

SELECT '1234' CHAR_NUMBER, TO_NUMBER('1234') FROM DUAL;
-- 문자는 왼쪽정렬, 숫자는 오른쪽 정렬

-- CHAR + CHAR 숫자 연산 가능한데 왜 굳이 NUMBER연산해야할까?
--
SELECT '1234'+'4321' FROM DUAL; -- 5555
SELECT '10,000' + '5,000' FROM DUAL; -- ERROR : invalid number
 -- 쉼표 때문에 에러. 사람이 인식하기에 ,는 숫자 자릿수 구분이지만
 --  컴퓨터한테는 쉼표가 붙어 숫자로 인식할 수 없게 된 것
SELECT TO_NUMBER('10,000') FROM DUAL; -- ERROR : invalid number
SELECT TO_NUMBER('10,000','999,999') FROM DUAL; -- 10000
-- 두번째 인자 : 지금 들어온 문자 타입이 이런 형식이라는 것을 인식시키는 기준
SELECT TO_NUMBER('10,000','999,999'), TO_NUMBER('5,000','999,999') FROM DUAL;--10000	5000
SELECT TO_NUMBER('10,000','999,999') + TO_NUMBER('5,000','999,999') FROM DUAL;--15000



SELECT TO_NUMBER('10,000','000,000') -- ERROR: ORA-01722: invalid number
FROM DUAL;                      -- 공백을 0으로 채우면 이상해지니 에러나는듯
SELECT TO_NUMBER('10,000','999,999') -- 10000
FROM DUAL;
-- TO_NUMBER+TO_NUMBER의 산술연산
SELECT TO_NUMBER('5000','999,999') + TO_NUMBER('5000','999,999')
FROM DUAL; -- ORA-01722: invalid number
           -- 에러원인 : 셋째자리에 ,받기로 했는데 ,이 없어서 에러
SELECT TO_NUMBER('5,000','999,999') + TO_NUMBER('5,000','999,999')
FROM DUAL; -- 10000




------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- 5)NULL처리 함수


-- NVL
-- null값을 지정한 값으로 대체하는 함수
--
-- 실제값을 바꾸는건 X
-- 대체할 값은 대체할려는 데이터의 타입을 따라가야한다 
--      ex)bonus의 데이터타입이 number이므로 숫자만가능

-- NULL을 다른 값으로 인지시키게 못하나?로부터 나오게 됨
SELECT EMP_NAME, BONUS, NVL(BONUS, 0) 
FROM EMPLOYEE;
SELECT NVL(BONUS,0) FROM EMPLOYEE;
SELECT NVL(BONUS,100) FROM EMPLOYEE;
SELECT NLV(BONUS, '보너스없음') FROM EMPLOYEE;



SELECT NVL(BONUS, '보너스X') -- ERROR : : invalid number
FROM EMPLOYEE; -- ex)bonus의 데이터타입이 number이므로 숫자만가능

-- NVL2
-- NVL2(컬럼명, NULL이면 이걸로 변경, NULL이 아니면 이걸로 변경)
-- NULL값이 존재한다면 두번째 인자값으로 변경, NULL값이 존재하지 않으면 세번째 인자값으로 변경
-- 해당데이터가 NULL이면 0.7로 아니면 0.5로 대체

SELECT NVL2(BONUS, 0, 100) FROM EMPLOYEE;
SELECT NVL2(BONUS, 50, 100,) FROM EMPLOYEE;
SELECT NVL2(BONUS,0.7,0.5) FROM EMPLOYEE;

-- NULLIF
-- 비교하는 값이 같으면 NULL, 다르면 앞에 있는 값 반환
-- (NULL)	123

SELECT NULLIF(123,123) FROM DUAL; -- 두 비교값이 같아 NULL반환
-- 데이터(컬럼명) 적용
SELECT EMP_NAME, NULLIF(EMPLOYEE.JOB_CODE, JOB.JOB_CODE) FROM EMPLOYEE, JOB;



------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- 6.선택함수

-- DECODE
-- DECODE(계산식|컬럼명, 조건값1, 선택값1, 조건값2, 선택값2, ...)
-- 계산식에 따라 조건값1에 맞으면 선택값1 반환, 조건값2에 맞으면 선택값2를 반환하는 함수
-- 범위를 다루는 >,< 같은 것들은 DECODE로 쓸 수 없다
-- JAVA SWITCH 스위치도 딱딱 수가 떨어지는 것만 가능

-- 주민번호 옆에 성별 같이 찍히도록 해볼 것
SELECT EMP_ID, EMP_NAME, EMP_NO,
        DECODE(SUBSTR(EMP_NO,8,1),1,'남',2,'여') 성별
FROM EMPLOYEE;
        

-- 직원의 급여를 인상하고자 한다
-- 직급코드가 J7인 직원은 급여의 10%를 인상하고
-- 직급코드가 J6인 직원은 급여의 15%를 인상하고
-- 직급코드가 J5인 직원은 급여의 20%를 인상하며
-- 그 외 직급의 직원은 급여의 5%만 인상한다
-- 직원 테이블에서 직원명, 직급코드, 급여, 인상급여(위 조건)을 조회

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

------------------------------------------------------------------------------


-- CASE ~ WHEN ~ THEN
-- CASE WHEN 조건식THEN 결과값
--      WHEN 조건식THEN 결과값
--      ELSE 결과값
-- END

-- 주민번호 + 성별 출력
SELECT EMP_NAME, EMP_NO,
        DECODE(SUBSTR(EMP_NO,8,1),1,'남',2,'여')
FROM EMPLOYEE;


-- 직원의 급여를 인상하고자 한다
-- 직급코드가 J7인 직원은 급여의 10%를 인상하고
-- 직급코드가 J6인 직원은 급여의 15%를 인상하고
-- 직급코드가 J5인 직원은 급여의 20%를 인상하며
-- 그 외 직급의 직원은 급여의 5%만 인상한다
-- 직원 테이블에서 직원명, 직급코드, 급여, 인상급여(위 조건)을 조회
SELECT EMP_NAME, JOB_CODE, SALARY,
        CASE WHEN JOB_CODE = 'J7' THEN SALARY*1.1
             WHEN JOB_CODE = 'J6' THEN SALARY*1.15
             WHEN JOB_CODE = 'J5' THEN SALARY*1.2
             ELSE SALARY*1.05
        END  "인상급여"
FROM EMPLOYEE;

-- 위와 같은 코드
-- CASE 공통된컬럼명 WHEN 조건식 THEN 결과
SELECT EMP_NAME, JOB_CODE, SALARY,
        CASE JOB_CODE WHEN 'J7' THEN SALARY*1.1
                      WHEN 'J6' THEN SALARY*1.15
                      WHEN 'J5' THEN SALARY*1.2
                      ELSE SALARY*1.05
        END "인상급여"
FROM EMPLOYEE;


-- 사번, 사원명, 급여, 등급조회
-- 등급 조건 : 급여가 500만보다 크면 1등급, 350만보다 크면 2등급, 200만보다 크면 3등급, 나머지는 4등급
-- DECODE로도 가능?
-- 범위를 다루는 >,< 같은 것들은 DECODE로 쓸 수 없다
-- JAVA SWITCH 스위치도 딱딱 수가 떨어지는 것만 가능
SELECT EMP_ID, EMP_NAME, SALARY,
        CASE WHEN SALARY> 5000000 THEN '1등급'
             WHEN SALARY> 3500000 THEN '2등급'
             WHEN SALARY> 2000000 THEN '3등급'
             ELSE '4등급'
        END "등급조회"
FROM EMPLOYEE;  -- 200	선동일	8000000	1등급

-- ERROR : 축약에러
SELECT EMP_ID, EMP_NAME, SALARY,
        CASE SALARY WHEN > 5000000 THEN '1등급' -- ERROR : 축약에러
                    WHEN > 3500000 THEN '2등급' -- ORA-00936: missing expression
                    WHEN > 2000000 THEN '3등급'
                    ELSE '4등급'
        END "등급조회"
FROM EMPLOYEE;



------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
---------------------------------- 그룹 함수 ----------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- 그룹 함수


-- SUM
-- 총합계
-- EMPLOYEE테이블에서 전 사원의 급여 총합

SELECT SUM(SALARY) FROM EMPLOYEE;

-- EMPLOYEE테이블에서 남자사원의 급여 총합
SELECT SUM(SALARY)
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) = 1;


-- AVG
-- 평균
-- EMPLOYEE테이블에서 전 사원의 급여 평균
 -- 3047662.60869565217391304347826086956522
 SELECT AVG(SALARY) FROM EMPLOYEE;
 
-- EMPLOYEE테이블에서 여자사원의 급여 총합
-- 2542030
SELECT AVG(SALARY)
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) = 2;

-- EMPLOYEE테이블에서 전 사원의 보너스 평균
-- BONUS가 NULL인 사원은 0으로 처리
-- 0.0847826086956521739130434782608695652174
-- SUM(BONUS)/23

SELECT AVG(NVL(BONUS,0))
FROM EMPLOYEE;




-- 0.2166666666666666666666666666666666666667
-- NULL을 가진 값은 평균 계산에서 제외되어 계산
-- SUM(BONUS)/9
SELECT AVG(BONUS)
FROM EMPLOYEE; -- 0.2166666666666666666666666666666666666667
SELECT SUM(BONUS)/9
FROM EMPLOYEE; -- 0.2166666666666666666666666666666666666667
SELECT SUM(BONUS)/23
FROM EMPLOYEE; -- 0.0847826086956521739130434782608695652174


-- MIN / MAX
-- 최소 / 최대
-- 숫자, 날짜, 문자도 가능
-- EMPLOYEE테이블에서 최소 급여와 최대 급여
-- 8000000	1380000
SELECT MAX(SALARY), MIN(SALARY) FROM EMPLOYEE; -- 8000000	1380000



-- 문자 넣기
SELECT MAX(EMP_NAME), MIN(EMP_NAME) FROM EMPLOYEE;
-- 날짜 넣기
SELECT MAX(HIRE_DATE), MIN(HIRE_DATE) FROM EMPLOYEE;


-- COUNT
-- NULL값은 제외하고 카운트
-- 23
-- 직원 23명 카운트함
SELECT COUNT(*) FROM EMPLOYEE; -- 전체 자료수를 카운트하는 듯


-- 21
-- NULL 2명을 제외한 21 반환
SELECT COUNT(DEPT_CODE) FROM EMPLOYEE;  -- 21

 

 

728x90
반응형
728x90

 

 

함수(FUNCTION)

함수(FUNCTION) 두 종류
A.단일 행 함수
B.그룹 함수

A.단일 행 함수
    1.문자 관련 함수 : LENGTH, INSTR,LPAD,LTRIM,TRIM,SUBSTR, CONCAT,REPLACE
    2.숫자 관련 함수 : ABS,MOD,ROUND,CEIL,FLOOR/TRUNC
    3.날짜 관련 함수 : MONTHS_BETWEEN, ADD_MONTHS, NEXT_DAY,LAST_DAT,EXTRACT
    4.형변환 함수 : TO_CHAR, TO_DATE, TO_NUMBER
    5.null처리 함수 : NVL, NVL2, NULLIF 
    6.선택 함수 : DECODE, CASE WHEN THEN
    
B.그룹함수
SUM, AVG, MIN/MAX, COUNT

---------------------------------------------------------------------------
---------------------------------------------------------------------------


 1.단일 행 함수
n개의 데이터를 넣으면 n개가 나오는 것
n개의 값을 읽어서 n개의 결과 리턴

2.그룹 함수
n개의 데이터를 넣으면 1개 나오는 것
n개의 값을 읽어 1개의 결과 리턴


Q. SELECT절에 단일 행 함수와 그룹 함수를 함께 사용할 수 있다/없다?
A. 없다

WHY?
result set의 결과는 테이블이었다
단일행 쓰면 여러 결과가 나오는데 그룹은 하나의 테이블이 나온다
같이 쓰면 테이블 하나가 제대로 안나오게 됨

-- SELECT절에 단일 행 함수와 그룹함수를 함께 사용할 수 없다
결과 행의 개수가 다르기 때문


함수를 사용할 수 있는 위치
SELECT 절
WHERE 절
GROUP BY 절
HAVING 절
ORDER BY 절
( 사실상 프론트빼고 다 가능)


<SELECT문 실행순서 및 사용형식>
1. FROM 테이블명 - 조회 대상 컬럼이 있는 테이블명 기술
2. WHERE 컬럼명 연산자 조건 - 행을 선택하는 조건을 기술
3. GROUP BY 컬럼명 } 계산식 - 그룹묶을 컬럼명, 계산식 기술
4. HAVING 그룹함수 연산자 비교값 - 그룹묶은 값들을 그룹함수로 계산후 선택을 위한 조건기술
5. SELECT * | [DISTINCT] 컬럼명, 계산식 [AS] 별칭
6. ORDER BY 컬럼명 | 별칭 | 컬럼순서 [ASC] | DESC
 
*/
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- 1.단일 행 함수
-- 1)문자 관련 함수
-- LENGTH / LENGTHB
-- 인자 : 문자,숫자,특수기호, 컬럼명 
-- B = BYTE
-- LENGTH  : 길이
-- LENGTHB : 글자의 바이트 사이즈 반환 
--      한글 : 3 byte
--      영어, 숫자, 특수기호 : 1 byte


SELECT LENGTH('AAAB') FROM DUAL;   -- 4
SELECT LENGTHB('AAAB') FROM DUAL;  -- 4
SELECT LENGTH('컴퓨터') FROM DUAL;  -- 3
SELECT LENGTHB('컴퓨터') FROM DUAL; -- 9

SELECT LENGTH(EMAIL), LENGTH(EMAIL) FROM EMPLOYEE;
-- 리터럴값도 가능하지만 컬럼도 가능

SELECT LENGTH(EMP_NAME), LENGTH(EMAIL) FROM EMPLOYEE;  -- 3	   15
-- 이름, 이메일 -> 길이, 바이트 사이즈

SELECT LENGTHB(EMP_NAME), LENGTHB(EMAIL) FROM EMPLOYEE; -- 9	15
SELECT EMP_NAME, LENGTHB(EMP_NAME), LENGTHB(EMP_NAME) FROM EMPLOYEE; -- 길이B 9
        
SELECT EMP_NAME, LENGTH(EMP_NAME), LENGTHB(EMP_NAME),
        EMAIL, LENGTH(EMAIL), LENGTHB(EMAIL)
FROM EMPLOYEE;



------------------------------------------------------------------------------
------------------------------------------------------------------------------


--  INSTR
-- 해당 문자열이 처음 나온 위치 인덱스번호 반환(ZERO-INDEX X)
-- INSTR(’문자열’or컬럼명, ‘찾아낼 문자‘,  시작 index, 2번째인자인 문자가 몇번째 나오는 문자인지)

--1번째 인자 : 찾을 문자열 or 컬럼명
--2번째 인자 : 첫번째 중에 찾고 싶은 문자
--3번째 인자 : 몇번째부터 읽기 시작할 것이냐. 안적으면 1부터 시작
--4번째 인자 : ' '의 문자가 세번째인자로부터 세기 시작해서 "몇번째로 나오는 문자인가”
--    1,2번째 인자는 리터럴( ‘ ‘ )로 감싼다
 
-- 없는 문자열은 0반환 // 만약, 제로인덱스였다면 -1반환
-- AABAACAABBAA
SELECT INSTR('AABAACAABBAA','A') FROM DUAL;   -- 1
SELECT INSTR('AABAACAABBAA','A',3) FROM DUAL; -- 4
SELECT INSTR('AABAACAABBAA','A',1,3) FROM DUAL; -- 4
SELECT INSTR('AABAACAABBAA','A',1,2) FROM DUAL; -- 2

SELECT INSTR('AABAACAABBAA','B') FROM DUAL;     -- 3
SELECT INSTR('AABAACAABBAA','B',1,1) FROM DUAL; -- 3
SELECT INSTR('AABAACAABBAA','B',1,2) FROM DUAL; -- 9
SELECT INSTR('AABAACAABBAA','B',9,2) FROM DUAL; -- 10

-- 코딩해설 : 7번쨰부터 읽기 시작해서 B가 처음 나올 때까지 읽어서, 처음 나오는 B의 위치 반환해
 SELECT INSTR('AABAACAABBAA','B',7,1) FROM DUAL; -- 9
 
 
-- 마이너스(-): 거꾸로 읽기
SELECT INSTR('AABAACAABBAA','B',-1) FROM DUAL; -- 10
SELECT INSTR('AABAACAABBAA','B',-1,1) FROM DUAL; -- 10
SELECT INSTR('AABAACAABBAA','B',-1,2) FROM DUAL; -- 9
SELECT INSTR('AABAACAABBAA','B',-1,3) FROM DUAL; -- 3

SELECT INSTR('AABAACAABBAA','B',-1,-1) FROM DUAL; -- ERROR : 4번째 인자는 양수만 가능
SELECT INSTR('AABAACAABBAA','B',-1,0) FROM DUAL;  -- ERROR : 4번째 인자는 양수만 가능
-- 역순 뒤에서 찍은 기준점 기준으로 왼쪽으로 세고 인덱스번호는 맨왼쪽에서 오른쪽으로


-- 1에서부터 두번째 있는 'B'를 찾아라
SELECT INSTR('AABAACAABBAA','B',1,2) FROM DUAL; -- 9

SELECT INSTR('AABAACAABBAA','B',1,2) FROM DUAL; -- 9


-- EMPLOYEE테이블에서 이메일의 @위치 반환

SELECT EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___@%';


------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- LPAD / RPAD
-- 왼쪽 공백 / 오른쪽 공백
-- 오른쪽 정렬 / 왼쪽 정렬
-- LPAD(컬럼명, 문자 총 길이,공백 대신 대체할 문자)
-- 주어진 값에 임의의 문자열을 왼쪽/오른쪽에 덧붙여 길이 n개의 문자열 반환
-- 전체 길이에서 남은 공간에 공백으로 채움


--      sun_di@kh.or.kr// 세팅 :20
SELECT LPAD('sun_di@kh.or.kr',20) FROM DUAL;
-- sun_di@kh.or.kr     //
SELECT RPAD('sun_di@kh.or.kr',20) FROM DUAL;



-- 값보다 지정한 총길이가 짧으면 뒤부터 짤림
SELECT LPAD('sun_di@kh.or.kr',5) FROM DUAL;
-- 공백대신 대체할 문자 삽입
SELECT LPAD('sun_di@kh.or.kr',20,'^') FROM DUAL;

------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- LTRIM / RTRIM
-- 좌/우에서부터 지정한 문자를 제거한 나머지 반환
--      문자를 지정하지 않을 경우, 공백 제거
-- LTRIM : 왼쪽부터 순서대로 제거
-- RTRIM : 오른쪽부터 순서대로 제거


-- 자바 STRING클래스에서 TRIM은 공백제거 메소드

-- KH//
SELECT LTRIM('   KH   ') FROM DUAL; -- KH   //
--    KH//
SELECT RTRIM('   KH   ')FROM DUAL; --    KH//

-- 000123456
-- 0만 제거하고 나머지를 반환
SELECT LTRIM('000123456',0) FROM DUAL;

-- 0001230456
-- 중간에 껴있는 해당 문자는 제거X
SELECT LTRIM('000123456',0) FROM DUAL;

-- ACABACCKH // KH
-- 'ABC' 묶여진 문자 하나로 보는게 아니라, A 또는 B 또는 C가 있으면 다 지우는 것
-- 'ABC' 안에 순서 상관X
SELECT LTRIM('ACABACCKH','ABC') FROM DUAL; -- KH

-- KH   // KH
-- 오른쪽부터 공백제거
SELECT LTRIM('KH   ') FROM DUAL; -- KH   //
SELECT RTRIM('KH    ') FROM DUAL; -- KH//

-- 01230456000 // 01230456
SELECT RTRIM('01230456000',0) FROM DUAL;
-- KHACABACC // KH
-- 오른쪽부터 지우기 시작
SELECT RTRIM('KHACABACC','ABC') FROM DUAL; -- KH



------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- TRIM
-- 앞/뒤/양쪽에서 지정한 문자를 제거한 나머지 반환
-- TRIM(제거방향 '제거할 문자 1개' FROM '찾을 문자열OR컬럼명')
-- LEADING : 앞부터 제거
-- TRAILING : 뒤부터 제거
-- BOTH : 양쪽에서부터 제거


--    KH   // KH // A는 별칭
SELECT TRIM('   KH   ') FROM DUAL; -- KH
SELECT TRIM(BOTH FROM '   KH   ') FROM DUAL; -- KH//
SELECT TRIM(BOTH ' ' FROM '   KH   ') FROM DUAL; -- KH//
SELECT TRIM(BOTH FROM '   KH   ') FROM DUAL; -- KH// 2번인자 제거할 문자 : 생략가능
SELECT TRIM(LEADING 'K' FROM '   KH   ') FROM DUAL; --    KH   // 공백에서 멈춰 K안지워짐
SELECT TRIM(TRAILING 'K' FROM '   KH   ') FROM DUAL; --    KH   //공백에서 멈춰 K안지워짐
SELECT TRIM(TRAILING ' ' FROM '   KH   ') FROM DUAL; --    KH//



-- ZZZKHZZZ // KH
SELECT TRIM(BOTH 'Z' FROM 'ZZZKHZZZ') FROM DUAL; -- KH
-- 123KH123123 // error : trim set should have only one character
-- TRIM은 제거할 문자 1개만 받는다
-- ZZZKHZZZ // KHZZZ
-- LEADING 앞부터 제거
SELECT TRIM(LEADING 'Z' FROM 'ZZZKHZZZ') FROM DUAL; -- KHZZZ

-- ZZZKHZZZZ // ZZZKH
-- TRAILING 뒤부터 제거
SELECT TRIM(TRAILING 'Z' FROM 'ZZZKHZZZZ') FROM DUAL; -- ZZZKH

-- ZZZKHZZZZ //KH
-- BOTH 양쪽에서부터 제거
SELECT TRIM(BOTH 'Z' FROM 'ZZZKHZZZ') FROM DUAL;  -- KH

--LTRIM/RTRIM처럼 인자 추가 형식이 아닌 
--코드 구조를 바꿔서 써야함 
--제거를 지우겠다 어디서부터? 컬럼명부터


------------------------------------------------------------------------------
------------------------------------------------------------------------------

--SUBSTR
-- String.substring()
--SUBSTR(컬럼명, 시작위치 인덱스, 시작위치부터 값을 반환할 길이)


-- HELLOMYGOODFRIENDS // YGOODFRIENDS
-- 7번째서부터 끝까지 반환
SELECT SUBSTR('HELLOMYGOODFRIENDS',7) FROM DUAL;

-- HELLOMYGOODFRINEDS // OM
-- 5번째 문자부터 2개만 반환
SELECT SUBSTR('HELLOMYGOODFRIENDS',5,2) FROM DUAL;

-- HELLOMYGOODFRINEDS // (null)
-- 5번쨰 문자부터 0개 반환 // 0개 반환이 불가능하기에 NULL 출력됨
SELECT SUBSTR('HELLOMYGOODFRIENDS',5,0) FROM DUAL; -- --(NULL)
-- HELLOMYGOODFRINEDS // HELLOM
SELECT SUBSTR('HELLOMYGOODFRIENDS',0,5) FROM DUAL; -- HELLO // 0부터 시작해도 1부터 적용
SELECT SUBSTR('HELLOMYGOODFRIENDS',1,5) FROM DUAL; -- HELLO // 0부터 시작해도 1부터 적용


-- HELLOMYGOODFRINEDS //  DFR
-- 뒤에서 8번째(D)부터 오른쪽으로 3개의 문자 반환
-- 위에서 마이너스(-)였으면 기준점이 뒤에서부터 세고 왼쪽방향으로 카운팅했지만 얘는 오른쪽으로 카운팅
SELECT SUBSTR('HELLOMYGOODFRIENDS',-8,3) FROM DUAL; -- DFR
-- HELLOMYGOODFRINEDS // OO
SELECT SUBSTR('HELLOMYGOODFRIENDS',-10,2) FROM DUAL;  -- OO
SELECT SUBSTR('HELLOMYGOODFRIENDS',-10,-2) FROM DUAL; -- 3RD 인자 몇번째문자인지가 -이면 NULL값


-- EMPLOYEE 테이블에서 이름, 이메일, 이메일의 아이디 조회
-- (이메일의 @ 도메인말고 아이디까지만)
SELECT EMP_NAME, EMAIL, SUBSTR(EMAIL,1,INSTR(EMAIL,'@')-1)
FROM EMPLOYEE;
-- 문제풀이 사고과정
-- 1.이메일 아이디의 규칙은 항상 @이 앞에 있음
-- 2. @ 위치 파악
-- 3. 1~@앞까지 찾기

-- EMPLOYEE 테이블에서 이름, 이메일, 이메일의 아이디 조회
-- (이메일의 @ 도메인말고 아이디까지만)
SELECT EMP_NAME, EMAIL,SUBSTR(EMAIL,1,INSTR(EMAIL,'@')-1)
FROM EMPLOYEE;


-- 주민등록번호를 이용하여 이름과 성별을 나타내는 부분 조회
-- EMPLOYEE 테이블에서 남자만 조회(사원명, '남')
-- EMPLOYEE 테이블에서 여자만 조회(사원명, '여')
SELECT EMP_NAME 사원명, CASE WHEN SUBSTR(EMP_NO,8,1)=1 THEN '남'
                            WHEN SUBSTR(EMP_NO,8,1)=2 THEN '여'
                       END 성별 
FROM EMPLOYEE;

SELECT EMP_NAME 사원명, DECODE(SUBSTR(EMP_NO,8,1),1,'남',2,'여') 성별
FROM EMPLOYEE;



-- EMPLOYEE테이블에서 직원들의 주민번호를 이용하여 사원명, 생년, 생월, 생일 조회
SELECT EMP_NAME 사원명,  SUBSTR(EMP_NO,1,2) 생년, SUBSTR(EMP_NO,3,2) 생월, SUBSTR(EMP_NO,5,2) 생일
FROM EMPLOYEE;



------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- LOWER / UPPER / INITCAP
-- INITCAP :각 단어의 첫글자만 대문자

-- 예제 Welcome To my World
-- welcome to my world
SELECT LOWER('Welcome To my World') FROM DUAL;
-- WELCOME TO MY WORLD
SELECT UPPER('Welcome To my World') FROM DUAL;
-- Welcome To My World
SELECT INITCAP('Welcome To my World') FROM DUAL;


------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- CONCAT
-- 문자열 이어붙이기

-- 가나다라123
SELECT CONCAT('가나다라','123') FROM DUAL;
SELECT CONCAT(DEPT_CODE, '-333') FROM EMPLOYEE; -- D9-333
SELECT CONCAT(JOB_CODE, ' BY S') FROM JOB; -- J1 BY S
SELECT CONCAT(DEPT_CODE, JOB_CODE) FROM EMPLOYEE; -- D9J1
-- 연결연산자 사용 : 가나다라123
-- 연결연산자 : ||
SELECT '가나다라' || '123' FROM DUAL; -- 가나다라123


------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- REPLACE
-- REPLACE(컬럼명,바꿔질 단어, 바꿀 단어)
-- 값 교체

-- 서울시 강남구 역삼동 // 서울시 강남구 삼성동
SELECT REPLACE('서울시 강남구 역삼동','역삼동','삼성동') FROM DUAL;

-- 강사님은 오라클을 수업중이다 // 선생님은 오라클을 수업중이다
-- 띄어쓰기 상관없이 적용가능
SELECT REPLACE('강사님은 오라클을 수업중이다','강사님','선생님') FROM DUAL;

-- 케이크 달다. 케이크 싫은사람? // 공부 달다. 공부 싫은사람?
-- 여러개 들어있어도 복수로 교체가능. 일치만 하면 전부 교체함
SELECT REPLACE('케이크 달다. 케이크 싫은사람?','케이크','단 거') FROM DUAL;

-- EMPLOYEE테이블에서 사원명, 주민번호 조회
-- 주민번호의 뒷자리는 *로 바꿔서 조회(EX.001122-*******)


-- REPLACE+SUBSTR

-- REPLACE+SUBSTR+INSTR


/*
REPLACE(EMP_NO,SUBSTR(EMP_NO,8,14/2)
SELECT REPLACE(EMP_NO,SUBSTR(EMP_NO,8,14/2)) FROM EMPLOYEE;
SELECT REPLACE(EMP_NO,SUBSTR(EMP_NO,8,LENGTH(EMP_NO)/2)) FROM EMPLOYEE;
SELECT LENGTH(EMP_NO)/2 FROM EMPLOYEE;
*/

-- RPAD+SUBSTR
SELECT EMP_NAME, RPAD(SUBSTR(EMP_NO,1,7),14,'*******')
FROM EMPLOYEE;


-- 방법1
-- REPLACE+SUBSTR 끝수 지정 & 미지정 


-- 방법2
-- RPAD+SUBSTR
SELECT EMP_NAME, REPLACE(EMP_NO,SUBSTR(EMP_NO,8,7),'*******') 주민번호
FROM EMPLOYEE;

-- RPAD+SUBSTR+INSTR
SELECT EMP_NAME, REPLACE(EMP_NO,SUBSTR(EMP_NO,8,7),'*******')
FROM EMPLOYEE;

-- RPAD+SUBSTR+INSTR+LENGTH
SELECT EMP_NAME, REPLACE(EMP_NO,SUBSTR(EMP_NO,INSTR(EMP_NO,'-')+1,LENGTH(EMP_NO)/2),'*******')
FROM EMPLOYEE;

-- 방법3
-- REPLACE+SUBSTR+INSTR+LENGTH


-- 방법4
-- SUBSTR+연결연산자(||)
SELECT EMP_NAME, SUBSTR(EMP_NO, 1, 7) || '*******' 주민번호
FROM EMPLOYEE;



------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- 2) 숫자 관련 함수


-- ABS
-- 절대값 반환
SELECT ABS(FLOOR(1.234)) FROM DUAL;
-- 10.9	10.9	10	10
-- 전부 양수 출력
SELECT ABS(-10.9), ABS(10.9), ABS(-10) FROM DUAL;

-- MOD
-- 모듈러
-- 나머지 구하기
-- MOD(나눠지는수 ,나누는 수)

-- 1	-1	1	-1	1.9
-- 내가 나누어지는 수에 대한 부호를 따라가게 됨
SELECT MOD(10,3), MOD(-10,3), MOD(10,-3), MOD(-10,-3), MOD(10.9,3) FROM DUAL;


-- ROUND
-- 몇번째 자리에서 반올림할지 소수점 자리수 지정가능
-- 123.456
-- 123	124	123	123.5	123.46	120	100
-- 소수점 자리지정 반올림
-- 소수점 -의 반올림
SELECT ROUND(123.456,0),ROUND(123.456), ROUND(123.456,1),ROUND(123.456,2), ROUND(123.456,-1) FROM DUAL;
SELECT ROUND(123.456,-1), ROUND(123.456,-2) FROM DUAL;

-- -11
-- 마이너스(-)의 반올림은?
-- 마이너스는 숫자가 클수록 작은 수 ex) -11이 -10보다 작은 수
-- -10.61에서 .61이 5이상이라 반올림이 되는데 -11로



-- CEIL
-- 124
-- 무조건 1의 자리에서 올림하게 되어있음
-- 자릿수 지정 불가. 다른 인자값 집어넣으면 에러
SELECT CEIL(123.456) FROM DUAL;


-- FLOOR / TRUNC
-- FLOOR : 수학적 내림(배웠던 수학의 내림) // 자릿수 지정 불가
-- TRUNC : 버림. 절삭. 몇번째 자리까지 버리겠다 // 자릿수 지정가능
SELECT FLOOR(123.456), TRUNC(123.456) FROM DUAL;
SELECT FLOOR(123.456), TRUNC(123.456,1) FROM DUAL;

-- 123	123	123.7
-- TRUNC : 몇번째 자리까지 버리겠다 자릿수 지정가능
-- 파이썬에서 FLOOR가 -쪽으로 내리고 TRUNC가 0쪽으로 수렴하는 것과 같은 개념
-- math.trunc(-3.14)   #결과는 -3
-- math.floor(-3.14)   #결과는 -4

 

 

 

728x90
반응형
728x90

 

연습문제 풀이

 

 



-- EMPLOYEE 테이블의 사번,이름,급여 조회
SELECT EMP_ID, EMP_NAME, SALARY FROM EMPLOYEEL

--EMPLOYEE 테이블의 모든 정보 조회
SELECT * FROM EMPLOYEE;

/*
-- 실습 문제 --
1.JOB 테이블의 모든 정보 조회
2.JOB 테이블의 직급 이름 조회
3.DEPARTMENT 테이블의 모든 정보 조회
4.EMPLOYEE 테이블의 직원명, 이메일, 전화번호, 고용일 조회
5.EMPLYEE 테이블의 고용일, 사원이름, 월급 조회
*/

--1.JOB 테이블의 모든 정보 조회
-- 방법1
SELECT * FROM JOB;

-- 방법2
SELECT JOB_CODE,JOB_NAME FROM JOB; 


--2.JOB 테이블의 직급 이름 조회
SELECT JOB_NAME FROM JOB;

--3.DEPARTMENT 테이블의 모든 정보 조회
-- 방법1
SELECT * FROM DEPARTMENT;

-- 방법2
SELECT DEPT_ID, DEPT_TITLE, LOCATION_ID FROM DEPARTMENT;

--4.EMPLOYEE 테이블의 직원명, 이메일, 전화번호, 고용일 조회
SELECT EMP_NAME,EMAIL,PHONE,HIRE_DATE FROM EMPLOYEE;

--5.EMPLYEE 테이블의 고용일, 사원이름, 월급 조회
SELECT HIRE_DATE, EMP_NAME,SALARY FROM EMPLOYEE;



--컬럼 값 산술 연산
--EMPLOYEE테이블에서 직원명, 연봉 조회(연봉 = 급여*12)
SELECT EMP_NAME, SALARY*12 연봉 FROM EMPLOYEE;

--EMPLOYEE테이블에서 직원명, 연봉, 보너스를 추가한 연봉 조회
-- 방법1
SELECT EMP_NAME, SALARY*12 연봉, SALARY*(1+BONUS) FROM EMPLOYEE;
--  수식에 NULL이 있으면 결과값에 NULL이 나옴 
-- 방법2
SELECT EMP_NAME 이름, SALARY * 12 연봉, SALARY*(1+BONUS)*12 AS 보너스
FROM EMPLOYEE;


/*
------------실습문제------------
1.EMPLOYEE테이블에서 이름, 연봉, 총수령액(보너스포함), 실수령액(총수령액-(연봉*세금3%)) 조회
2.EMPLOYEE테이블에서 이름, 고용일, 근무일수(오늘 날짜 - 고용일) 조회 
 - 오늘날짜 SYSDATE
*/
--(SALARY+SALARY*BONUS)*12
SELECT EMP_NAME 이름, SALARY * 12 연봉,SALARY *(1+BONUS)*12 "총수령액(보너스포함)", 
        SALARY *(1+BONUS)*12 - SALARY*12*0.03 AS 실수령액
FROM EMPLOYEE;




 

-- 컬럼 별칭
-- 컬럼명  AS 별칭 / 컬럼명 AS “별칭” / 컬럼명 별칭 / 컬럼명 “별칭”



/*
리터럴(literal)
값 자체 ‘ ‘

오라클에서는 문자,문자열,데이트 상관없이 다 싱글쿼테이션(’ ‘)으로 감싸준다
데이터 타입에 상관없이 별칭(””) 외에는 다 싱글쿼테이션으로 감싼다
*/ 

-- EMPLOYEE 테이블에서 직원의 직원 번호, 사원명, 급여, 단위 조회




-- 별칭 : "" 
-- 리터럴을 싱글쿼테이션으로 처리한다 : ' '
-- '원'이라는 컬럼을 보여주고 싶지않으면 더블쿼테이션""으로 단위써주자



-- EMPLOYEE테이블에서 직원의 직급 코드 조회

-- bang으로 시작하는 email 다 조회
-- 결과 : 방명수 bang ns@kh.kr
SELECT EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE 'bang%';

-- 결과 : 없음
SELECT EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE 'Bang%';
-- 리터럴은 대소문자 철저히 구별하기에 대문자 BANG으로 시작하는 EMAIL이 없어서 안나온 것



-- EMPLOYEE 테이블에서 직원의 부서 코드를 중복 없이 조회
SELECT DISTINCT DEPT_CODE
FROM EMPLOYEE;


-- DISTINCT는 한번만 쓸 수 있다
--SELECT DISTINCT DEPT_CODE, DISTINCT DEPT_CODE -- error
--FROM EMPLOYEE;



/*
SELECT 컬럼명 -- 조회하고자 하는 컬럼명 기술
FROM 테이블명 -- 조회하고자 하는 컬림이 포함된 테이블명 기술
WHERE 조건식; -- 행을 선택하는 조건 기술, 조건을 만족하는 행만 반환
             -- 조건식 복수로 붙여서 사용가능. 복수라도 WHERE절 한개만 기술


--비교연산자
>, <, >=, <=, = ,!= 

크다, 작다, 크거나 같다
같다 : =
같지않다 : != , ^= , <>
*/

--EMPLOYEE테이블에서 부서코드가 'D9'인 직원의 이름, 부서코드 조회
SELECT  EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9';



-- '' 없이 D9만 쓰면 컬럼으로 인지하게 됨
-- 'd9'라고 써도 안됨. 리터럴은 대소문자 구분



--급여가 4000000이상인 직원의 이름, 급여 조회
-- ''로 감싸도 숫자로 인지잘한다. '' 없어도 됨
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY >= 4000000;




-- EMPLOYEE테이블에서 부서코드가 D9이 아닌 사원의 사번, 이름, 부서코드조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE != 'D9';
--WHERE DEPT_CODE ^= 'D9';
--WHERE DEPT_CODE <> 'D9';



-- EMPLOYEE 테이블에서 퇴사 여부가 N인 직원을 조회하고 근무 여부를 재직중으로 표시
-- 사번,이름, 고용일, 근무여부 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE, '근무 여부' 재직중
FROM EMPLOYEE
WHERE ENT_YN = 'N';




-------------- 실습문제 --------------
--1.EMPLOYEE테이블에서 월급이 3000000이상인 사원의 이름, 월급, 고용일 조회
--2.EMPLOYEE테이블에서 SAL_LEVEL이 S1인 사원의 이름, 월급, 고용일, 연락처 조회
--3.EMPLOYEE테이블에서 실수령액(총수령액-(연봉*세금3%))이 5천만원 이상인 
--  사원의 이름, 급여, 실수령액, 고용일 조회

SELECT EMP_NAME, SALARY, HIRE_DATE
FROM EMPLOYEE
WHERE SALARY >= 3000000;

SELECT EMP_NAME, SALARY, HIRE_DATE, PHONE
FROM EMPLOYEE
WHERE SAL_LEVEL = 'S1';

SELECT EMP_NAME, SALARY, SALARY+SALARY*(SALARY*BONUS)-(SALARY*12*0.03)실수령액, HIRE_DATE
FROM EMPLOYEE
WHERE SALARY+SALARY*(SALARY*BONUS)-(SALARY*12*0.03) >= 5000000;

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------



-- 논리 연산자 AND OR
-- EMPLOYEE 테이블에서 부서코드가 D6이고 급여를 3000000보다 많이 받는 직원의 이름, 부서코드, 급여 조회
SELECT EMP_NAME, DEPT_CODE,SALARY  
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' AND SALARY > 3000000;


-- EMPLOYEE 테이블에서 부서코드가 D6이거나 급여를 3000000보다 많이 받는 직원의 이름,부서코드, 급여조회
SELECT  EMP_NAME, DEPT_CODE,SALARY 
FROM EMPLOYEE
WHERE   DEPT_CODE = 'D6' OR SALARY > 3000000;




-- 1.EMPLOYEE 테이블에서 월급이 4000000이상이고 JOB_CODE가 J2인 사원의 전체 내용 조회
-- 2.EMPLOYEE 테이블에 DEPT_CODE가 D9이거나 D5인 사원 중에 고용일이 02년 1월 1일보다 빠른 사원의
--   이름, 부서코드, 고용일 조회
SELECT *  
FROM EMPLOYEE
WHERE SALARY >= 4000000 AND JOB_CODE ='J2';

SELECT EMP_NAME, DEPT_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9' OR HIRE_DATE < '02/01/01';

--- 다시풀이
SELECT *
FROM EMPLOYEE
WHERE SALARY >= 4000000 AND JOB_CODE = 'J2';

SELECT  EMP_NAME, DEPT_CODE, HIRE_DATE 
FROM EMPLOYEE
WHERE  (DEPT_CODE = 'D9' OR DEPT_CODE = 'D5')
        AND HIRE_DATE < '02/01/01' ;

-- 이 코드는 틀린 코드
-- 기준일보다 작은게 빠른 것. 오늘보다 내일이 더 큰 숫자
-- 날짜를 기준으로 조건식을 쓴다면 ''로 감싸줘야한다
-- 자바나 SQL이나 OR AND는 AND가 우선순위로 먼저 연산
-- OR를 먼저 연산하고 싶다면 소괄호를 쳐줄 것





------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- BETWEEN AND
-- ~이상 ~이하

-- EMPLOYEE 테이블에서 급여를 3500000이상 6000000이하를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE  
WHERE SALARY >= 3500000 AND SALARY <= 6000000;

SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE 
WHERE SALARY BETWEEN 3500000 AND 6000000;

---다시 풀이
SELECT  EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE 
FROM EMPLOYEE
WHERE SALARY BETWEEN 3500000 AND 6000000;
SELECT  EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE 
FROM EMPLOYEE
WHERE SALARY>=3500000 AND SALARY <=6000000;


-- 반대로 급여를 3500000미만 6000000초과를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
--WHERE SALARY < 3500000 OR SALARY > 6000000; 
--WHERE SALARY NOT BETWEEN 3500000 AND 6000000;
WHERE NOT SALARY BETWEEN 3500000 AND 6000000;

-------실습문제-------
-- 1.EMPLOYEE 테이블에 고용일이 90/01/01 ~ 01/01/01인 사원의 전체 내용을 조회
-- 시간의축을 가로선상에 놓고 보면 시간과 연산자 사용계산이 쉬워짐

SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';

SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE BETWEEN '90/01/01' AND  '01/01/01';

-- WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';

---다시풀이
SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE BETWEEN '90/01/01' AND '01/01/01';
SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <='01/01/01';


------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

/*
-- LIKE
비교하려는 값이 특정 패턴을 만족시키는지 조회
ex) 이멜에 i가 들어가는 것을 조회, 이름이 김씨가 들어간 사람들 조회

와일드카드 2종류
 _ : 1글자
 % : 0글자 이상

ex)
'_' (한글자)
'__' (두글자)
'___' (세글자)

 '글자%' : 글자로 시작하는 값
    글자 뒤로 뭐가와도 ok
    ex) 글자최고, 글자(공백), 글자왕, 글자
 '%글자' : 글자로 끝나는 값
    글자 앞에 뭐가와도 ok
    ex) 먹글자, 한글은 글자, (공백)글자
 '글%자' : 글로 시작해서 자로 끝나는 값
    글과 자 사이 뭐가와도 ok
    ex)글씨를 잘쓰자, 글자, 글과자, 글(공백)자
 '%글자%' : 글자가 포함되어있는 값
        ex) 한글자값, 먹글자, 글자, 한두글자

*/

--EMPLOYEE 테이블에서 성이 전씨인 사원의 사번, 이름, 고용일 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE
FROM EMPLOYEE
WHERE EMP_NAME LIKE '전%';
-- WHERE EMP_NAME LIKE '전__';
-- 도 가능하나 이름이 세글자인 사람들만 가능해서 이름이 두글자나 네글자이상이면 정확도가 떨어짐



--EMPLOYEE 테이블에서 이름이 '하'가 포함된 직원의 이름, 주민번호, 부서코드 조회
SELECT EMP_NAME, EMP_NO, DEPT_CODE
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%하%';


--EMPLOYEE 테이블에 전화번호 4번째 자리가 9로 시작하는 사원의 사번, 이름, 전화번호 조회
-- 전번 양식 : 01012345678
-- 01X 세자리 + 9로 시작하는 네번지째 자릿수
SELECT EMP_ID, EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE LIKE '___9%';

---RE
SELECT EMP_ID, EMP_NAME,PHONE
FROM EMPLOYEE
WHERE PHONE LIKE '___9%';


--EMPLOYEE 테이블에서 이메일 중 _의 앞 글자가 3자리인 이메일 주소를 가진 사원의 사번, 이름, 이메일 주소 조회
SELECT EMP_ID, EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___ _%' ESCAPE ' ';

--RE
SELECT EMP_ID, EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___!_%' ESCAPE '!';



/*
LIKE를 쓸 때 패턴!
와일드카드 : _ %
각각 한글자,와 0글자 이상을 나타내는 와일드 카드

세글자 자릿수 언더바 3개 + 검색하고자 하는 데이터로의 언더바 1개 = 총4개의 언더바
검색하고자 하는 패턴의 문자와 와일드 카드가 일치할 경우에는 패턴과 와일드 카드를 구분하지 못하기 때문에
ESCAPE OPTION을 통해 구분해준다
 - 패턴(데이터)으로 쓸 것 앞에 구분기호 사용

*/


------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------



--  ESCAPE 식별자

-- EMPLOYEE테이블에서 김씨 성이 아닌 직원의 사번, 이름, 고용일 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE
FROM EMPLOYEE
--WHERE EMP_NAME NOT LIKE '김%';
WHERE NOT EMP_NAME LIKE '김%';

---RE
SELECT EMP_ID, EMP_NAME, HIRE_DATE
FROM EMPLOYEE
WHERE EMP_NAME NOT LIKE '김%';

--WHERE NOT EMP_NAME LIKE '김%';
-- NOT 순서 : 해당 컬럼명 앞뒤 둘 다 가능

/*
WHERE EMP_NAME != '김%'; 
 = 혹은 != '김%'으로 검색하면 '김%' 데이터자체를 검색
LIKE '김%' 뒤에 어떤게 오든 상관없다
LIKE와 사용하는 % _ 는 와일드카드 적용받는다    
    LIKE는 문자에 대한 패턴 검색하는 것

!= '김%'에서는 이름이 김%인 사람을 찾는 것(리터럴 김% 데이터를 찾는 것)
    여기서 %는 와일드카드로 적용이 되지 않고 그냥 순수 기호 %인 것

*/

-----------실습문제-----------
--1.EMPLOYEE 테이블에서 이름 끝이 '연'으로 끝나는 사원 이름 조회
--2.EMPLOYEE 테이블에서 전화번호 처음 세자리가 010이 아닌 사원의 이름, 전화번호 조회
--3.EMPLOYEE 테이블에서 메일주소 _의 앞이 4자이면서 DEPT_CODE가 D9 또는 D6이고
--  고용일이 90/01/01 ~ 00/12/01이고, 급여가 2700000만 이상인 사원의 전체 정보 조회
SELECT EMP_NAME
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%연';

SELECT EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';

SELECT *
FROM EMPLOYEE
WHERE EMAIL LIKE '____!_%' ESCAPE '!'
        AND (DEPT_CODE = 'D9' OR DEPT_CODE = 'D6')
        -- AND (HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '00/12/01')
        AND HIRE_DATE BETWEEN '90/01/01' AND '00/12/01'
        AND SALARY >= 2700000;


---RE
SELECT EMP_NAME
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%연';

SELECT EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';

SELECT *
FROM EMPLOYEE
WHERE EMAIL LIKE '____!_%' ESCAPE '!' 
            AND (DEPT_CODE = 'D9' OR DEPT_CODE = 'D6')
            AND HIRE_DATE BETWEEN '90/01/01' AND '00/12/01'
            AND SALARY >= 2700000;

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- IS NULL
-- IS NOT NULL
-- 컬럼값이 NULL이냐
-- 컬럼값이 NULL이 아니냐

--EMPLOYEE 테이블에서 보너스를 받지 않는 사원의 사번, 이름, 급여, 보너스 조회
SELECT EMP_ID, EMP_NAME,SALARY,BONUS
FROM EMPLOYEE
WHERE BONUS IS NULL;
---RE
SELECT EMP_ID, EMP_NAME,SALARY,BONUS
FROM EMPLOYEE
WHERE BONUS IS NULL;

--WHERE BONUS = NULL; 값 안나옴
--WHERE BONUS = (null); 값 안나옴

--EMPLOYEE 테이블에서 보너스를 받는 사원의 사번, 이름, 급여, 보너스 조회
SELECT EMP_ID, EMP_NAME,SALARY,BONUS
FROM EMPLOYEE
WHERE BONUS IS NOT NULL;
WHERE NOT BONUS IS NULL;
---RE
SELECT EMP_ID, EMP_NAME,SALARY,BONUS
FROM EMPLOYEE
WHERE BONUS IS NOT NULL;

-- WHERE NOT BONUS IS NULL; 
-- NOT은 컬렴명 앞에 붙어도 가능

--WHERE BONUS NOT LIKE '%(null)%';


-- EMPLOYEE 테이블에서 관리자도 없고 부서 배치도 받지 않은 직원의 이름, 관리자, 부서코드 조회
-- EMPLOYEE 테이블에서 부서 배치를 받지 않았지만 보너스를 지급받는 직원의 이름,  보너스, 부서코드 조회
SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;


SELECT EMP_NAME, BONUS, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE IS NULL AND BONUS IS NOT NULL;

---RE
SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;

SELECT EMP_NAME, BONUS, DEPT_CODE
FROM EMPLOYEE 
WHERE DEPT_CODE IS NULL AND BONUS IS NOT NULL;


------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------


--IN
-- 목록에 일치하는 값이 있으면 TRUE가 되어 값 반환
-- 목록에 일치하는 값이 있으면 TRUE를 반환


-- D6부서와 D9부서원들의 이름, 부서코드, 급여 조회
-- 직급코드가 J1, J2, J3, J4인 사람들의 이름, 직급코드, 급여 조회
SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' OR DEPT_CODE = 'D9';

SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
--WHERE JOB_CODE = 'J1' OR JOB_CODE = 'J2' OR JOB_CODE = 'J3' OR JOB_CODE =  'J4';
WHERE JOB_CODE IN ('J1','J2','J3','J4'); 

---RE
SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE JOB_CODE IN ('J1','J2','J3','J4');


-- 소괄호로 처음 들어가서 D6를 맞딱들이고 각 조건 체크해서 반환. 다음 D9체크



------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- 연결 연산자 ||
-- 자바에서의 or논리연산자의 기호가 SQL에서는 연결연산자
-- EMPLOYEE테이블에서 사번, 이름, 급여를 연결해서 조회 (EX. 200선동일8000000)
SELECT EMP_ID || EMP_NAME || SALARY 급여
FROM EMPLOYEE;


-- EMPLOYEE테이블에서 ' "사원명"의 월급은 "급여"원입니다' 형식으로 조회
SELECT EMP_NAME ||'명의 월급은' || SALARY ||'원 입니다'
FROM EMPLOYEE;
-- 문장으로 쓰고 싶을 경우 필요

---RE
SELECT EMP_NAME, EMAIL || ' 이메일 주소 '||'힘내'
FROM EMPLOYEE;


------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------




--BETWEEN
-- 반대로 급여를 3500000미만 6000000초과를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회

SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
--WHERE SALARY BETWEEN 3500000 AND 6000000;
WHERE SALARY NOT BETWEEN 3500000 AND 6000000;
-- 1.EMPLOYEE 테이블에 고용일이 90/01/01 ~ 01/01/01인 사원의 전체 내용을 조회 (BETWEEN 사용)
SELECT *
FROM EMPLOYEE
--WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';
WHERE HIRE_DATE BETWEEN '90/01/01' AND '01/01/01';

-- LIKE
--EMPLOYEE 테이블에서 이메일 중 _의 앞 글자가 3자리인 이메일 주소를 가진 사원의 사번의 사번, 이름, 이메일 주소 조회
SELECT EMP_ID, EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___^_%' ESCAPE '^';

-- NULL
-- EMPLOYEE 테이블에서 부서 배치를 받지 않았지만 보너스를 지급받는 직원의 이름,  보너스, 부서코드 조회
SELECT EMP_NAME, BONUS, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE IS NULL AND BONUS IS NOT NULL;

-- IN
-- 직급코드가 J1, J2, J3, J4인 사람들의 이름, 직급코드, 급여 조회
SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
--WHERE JOB_CODE = 'J1' OR JOB_CODE = 'J2' OR JOB_CODE = 'J3' OR JOB_CODE = 'J4';
WHERE JOB_CODE IN ('J1','J2','J3','J4');

-----------실습문제-----------
--1.EMPLOYEE 테이블에서 이름 끝이 '연'으로 끝나는 사원 이름 조회
--2.EMPLOYEE 테이블에서 전화번호 처음 세자리가 010이 아닌 사원의 이름, 전화번호 조회
--3.EMPLOYEE 테이블에서 메일주소 _의 앞이 4자이면서 DEPT_CODE가 D9 또는 D6이고
--  고용일이 90/01/01 ~ 00/12/01이고, 급여가 2700000만 이상인 사원의 전체 정보 조회

SELECT EMP_NAME
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%연';

SELECT EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';

SELECT  *
FROM EMPLOYEE
WHERE EMAIL LIKE '____!_%' ESCAPE '!' 
        AND (DEPT_CODE 'D9' OR DEPT_CODE 'D6')
        AND HIRE_DATE '90/01/01' AND '00/12/01'
        AND SALARY >= 2700000;

 

 

 

 

728x90
반응형
728x90

 

 



--BETWEEN
-- 반대로 급여를 3500000미만 6000000초과를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회

SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
--WHERE SALARY BETWEEN 3500000 AND 6000000;
WHERE SALARY NOT BETWEEN 3500000 AND 6000000;
-- 1.EMPLOYEE 테이블에 고용일이 90/01/01 ~ 01/01/01인 사원의 전체 내용을 조회 (BETWEEN 사용)
SELECT *
FROM EMPLOYEE
--WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';
WHERE HIRE_DATE BETWEEN '90/01/01' AND '01/01/01';

-- LIKE
--EMPLOYEE 테이블에서 이메일 중 _의 앞 글자가 3자리인 이메일 주소를 가진 사원의 사번의 사번, 이름, 이메일 주소 조회
SELECT EMP_ID, EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___^_%' ESCAPE '^';

-- NULL
-- EMPLOYEE 테이블에서 부서 배치를 받지 않았지만 보너스를 지급받는 직원의 이름,  보너스, 부서코드 조회
SELECT EMP_NAME, BONUS, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE IS NULL AND BONUS IS NOT NULL;

-- IN
-- 직급코드가 J1, J2, J3, J4인 사람들의 이름, 직급코드, 급여 조회
SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE JOB_CODE = 'J1' OR JOB_CODE = 'J2' OR JOB_CODE = 'J3' OR JOB_CODE = 'J4';


-----------실습문제-----------
--1.EMPLOYEE 테이블에서 이름 끝이 '연'으로 끝나는 사원 이름 조회
--2.EMPLOYEE 테이블에서 전화번호 처음 세자리가 010이 아닌 사원의 이름, 전화번호 조회
--3.EMPLOYEE 테이블에서 메일주소 _의 앞이 4자이면서 DEPT_CODE가 D9 또는 D6이고
--  고용일이 90/01/01 ~ 00/12/01이고, 급여가 2700000만 이상인 사원의 전체 정보 조회

SELECT EMP_NAME
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%연';

SELECT EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';

SELECT  *
FROM EMPLOYEE
WHERE EMAIL LIKE '____!_%' ESCAPE '!' 
        AND (DEPT_CODE 'D9' OR DEPT_CODE 'D6')
        AND HIRE_DATE '90/01/01' AND '00/12/01'
        AND SALARY >= 2700000;

 

728x90
반응형
728x90

 

SELECT

데이터 ’조회’

SELECT 컬럼명 FROM 테이블명;

방법1
SELECT EMP_ID,EMP_NAME,SALARY FROM EMPLOYEE;

방법2
SELECT EMP_ID,EMP_NAME, SALARY
FROM EMPLOYEE;

 

SELECT 컬럼명 -- 조회하고자 하는 컬럼명 기술
FROM 테이블명 -- 조회하고자 하는 컬림이 포함된 테이블명 기술
WHERE 조건식; -- 행을 선택하는 조건 기술, 조건을 만족하는 행만 반환
                     -- 조건식 복수로 붙여서 사용가능. 복수라도 WHERE절 한개만 기술

 

한 테이블의 모든 정보 조회

--EMPLOYEE 테이블의 모든 정보 조회
방법1
SELECT EMP_ID,EMP_NAME, EMP_NO, EMAIL, PHONE, DEPT_CODE, JOB_CODE, SAL_LEVEL, SALARY,
        BONUS, MANAGER_ID, HIRE_DATE, ENT_DATE, ENT_YN FROM EMPLOYEE ;
 
방법2
SELECT * -- * : 전체
FROM EMPLOYEE;

 


 

 DISTINCT

중복제거

DISTINCT는 한번만 쓸 수 있다

-- DISTINCT : 중복제거
SELECT DISTINCT JOB_CODE
FROM EMPLOYEE;

-- EMPLOYEE 테이블에서 직원의 부서 코드를 중복 없이 조회
SELECT DISTINCT DEPT_CODE
FROM EMPLOYEE;

-- DISTINCT는 한번만 쓸 수 있다
--SELECT DISTINCT DEPT_CODE, DISTINCT DEPT_CODE -- ERROR
--FROM EMPLOYEE;

 

DISTINCT A,B 콤마로 같이 쓰면 ()로 묶은 효과 발생

콤마로 두 컬럼을 묶으면 두 컬럼의 조건이

AND조건으로 교집합 된 것만 중복 제거한다

SELECT DISTINCT DEPT_CODE, JOB_CODE -- 콤마로 두 컬럼을 묶으면 두 컬럼의 조건이  
FROM EMPLOYEE;                      -- AND조건으로 교집합 된 것만 중복 제거한다

 


 

리터럴(literal)

값 자체

싱글쿼테이션( ' ' )

오라클에서는 문자,문자열,데이트 상관없이 다 싱글쿼테이션(’ ‘)으로 감싸준다

컬럼 별칭

컬럼명  AS 별칭 / 컬럼명 AS “별칭” / 컬럼명 별칭 / 컬럼명 “별칭”

별칭 : "" 

쌍따옴표( “”)를 무조건 붙여야하는 조건

1)별칭에 특수문자가 들어갈 경우
2)별칭이 숫자로 시작할 경우
쌍따옴표 = 더블 쿼테이션(” ”)
    EX) 직원 명 ←띄어쓰기 공백 특수문자라 “직원 명”으로 적어줘야한다
    EX) SALARY*12 AS 연봉

 

-- EMPLOYEE 테이블에서 직원의 직원 번호, 사원명, 급여, 단위 조회
SELECT EMP_ID, EMP_NAME, SALARY, '원' "단위"
FROM EMPLOYEE;
SELECT EMP_ID, EMP_NAME, SALARY, '원입니다' "단위"
FROM EMPLOYEE;
-- 별칭 : "" 
-- 리터럴을 싱글쿼테이션으로 처리한다 : ' '
-- '원'이라는 컬럼을 보여주고 싶지않으면 더블쿼테이션""으로 단위써주자

 




비교연산자

>, <, >=, <=, = ,!= 

크다, 작다, 크거나 같다
같다 : =
같지않다 : != , ^= , <>

--EMPLOYEE테이블에서 부서코드가 'D9'인 직원의 이름, 부서코드 조회
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9'; 
-- '' 없이 D9만 쓰면 컬럼으로 인지하게 됨
-- 'd9'라고 써도 안됨. 리터럴은 대소문자 구분


-- 급여가 4000000이상인 직원의 이름, 급여 조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY >= '4000000'; -- ''로 감싸도 숫자로 인지잘한다. '' 없어도 됨

-- EMPLOYEE테이블에서 부서코드가 D9이 아닌 사원의 사번, 이름, 부서코드조회
SELECT EMP_NO, EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE != 'D9'; -- != //  ''이랑 대소문자 구별 주의
WHERE DEPT_CODE ^= 'D9'; -- ^=
WHERE DEPT_CODE <> 'D9'; -- <>

 

 

 

전체코드

-- 컬럼 별칭
-- 컬럼명  AS 별칭 / 컬럼명 AS “별칭” / 컬럼명 별칭 / 컬럼명 “별칭”
SELECT EMP_NAME "직원 명", SALARY * 12 급여,SALARY *(1+BONUS)*12 총수령액, SALARY *(1+BONUS)*12 - SALARY*12*0.03 실수령액
FROM EMPLOYEE;

SELECT EMP_NAME,HIRE_DATE, SYSDATE-HIRE_DATE AS 근무일수
FROM EMPLOYEE;


/*
리터럴(literal)
값 자체 ‘ ‘

오라클에서는 문자,문자열,데이트 상관없이 다 싱글쿼테이션(’ ‘)으로 감싸준다
데이터 타입에 상관없이 별칭(””) 외에는 다 싱글쿼테이션으로 감싼다
*/ 

-- EMPLOYEE 테이블에서 직원의 직원 번호, 사원명, 급여, 단위 조회
SELECT EMP_ID, EMP_NAME, SALARY, '원' "단위"
FROM EMPLOYEE;
SELECT EMP_ID, EMP_NAME, SALARY, '원입니다' "단위"
FROM EMPLOYEE;
-- 별칭 : "" 
-- 리터럴을 싱글쿼테이션으로 처리한다 : ' '
-- '원'이라는 컬럼을 보여주고 싶지않으면 더블쿼테이션""으로 단위써주자

-- EMPLOYEE테이블에서 직원의 직급 코드 조회
SELECT JOB_CODE, '직급코드'
FROM EMPLOYEE;

select emp_name, email
from employee
where email like 'bang%'; -- bang으로 시작하는 email 다 조회
-- 결과 : 방명수 bang ns@kh.kr
-- 오라클은 대소문자 구분안해서 소문자로 써도 되나 리터럴에서는 엄격히 구분하기에 주의

SELECT EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE 'BANG%';
-- 결과 : 없음
-- 리터럴은 대소문자 철저히 구별하기에 대문자 BANG으로 시작하는 EMAIL이 없어서 안나온 것



------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------



-- DISTINCT : 중복제거
SELECT DISTINCT JOB_CODE
FROM EMPLOYEE;

-- EMPLOYEE 테이블에서 직원의 부서 코드를 중복 없이 조회
SELECT DISTINCT DEPT_CODE
FROM EMPLOYEE;

-- DISTINCT는 한번만 쓸 수 있다
--SELECT DISTINCT DEPT_CODE, DISTINCT DEPT_CODE
--FROM EMPLOYEE;

SELECT DISTINCT DEPT_CODE, DEPT_CODE
FROM EMPLOYEE;


/*
SELECT 컬럼명 -- 조회하고자 하는 컬럼명 기술
FROM 테이블명 -- 조회하고자 하는 컬림이 포함된 테이블명 기술
WHERE 조건식; -- 행을 선택하는 조건 기술, 조건을 만족하는 행만 반환
             -- 조건식 복수로 붙여서 사용가능. 복수라도 WHERE절 한개만 기술




------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------



-- 비교연산자
>, <, >=, <=, = ,!= 

크다, 작다, 크거나 같다
같다 : =
같지않다 : != , ^= , <>
*/
--EMPLOYEE테이블에서 부서코드가 'D9'인 직원의 이름, 부서코드 조회
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9'; 
-- '' 없이 D9만 쓰면 컬럼으로 인지하게 됨
-- 'd9'라고 써도 안됨. 리터럴은 대소문자 구분


-- 급여가 4000000이상인 직원의 이름, 급여 조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY >= '4000000'; -- ''로 감싸도 숫자로 인지잘한다. '' 없어도 됨

-- EMPLOYEE테이블에서 부서코드가 D9이 아닌 사원의 사번, 이름, 부서코드조회
SELECT EMP_NO, EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE != 'D9'; -- != //  ''이랑 대소문자 구별 주의
WHERE DEPT_CODE ^= 'D9'; -- ^=
WHERE DEPT_CODE <> 'D9'; -- <>

-- EMPLOYEE 테이블에서 퇴사 여부가 N인 직원을 조회하고 근무 여부를 재직중으로 표시
-- 사번,이름, 고용일, 근무여부 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE, '재직중' "근무여부"
FROM EMPLOYEE 
WHERE ENT_YN = 'N';


-------------- 실습문제 --------------
--1.EMPLOYEE테이블에서 월급이 3000000이상인 사원의 이름, 월급, 고용일 조회
--2.EMPLOYEE테이블에서 SAL_LEVEL이 S1인 사원의 이름, 월급, 고용일, 연락처 조회
--3.EMPLOYEE테이블에서 실수령액(총수령액-(연봉*세금3%))이 5천만원 이상인 
--  사원의 이름, 급여, 실수령액, 고용일 조회


--1.EMPLOYEE테이블에서 월급이 3000000이상인 사원의 이름, 월급, 고용일 조회
SELECT EMP_NAME, SALARY, HIRE_DATE
FROM EMPLOYEE
WHERE SALARY >= 3000000;

--2.EMPLOYEE테이블에서 SAL_LEVEL이 S1인 사원의 이름, 월급, 고용일, 연락처 조회
SELECT EMP_NAME, SALARY, HIRE_DATE, PHONE
FROM EMPLOYEE
WHERE SAL_LEVEL = 'S1';

--3.EMPLOYEE테이블에서 실수령액(총수령액-(연봉*세금3%))이 5천만원 이상인 
--  사원의 이름, 급여, 실수령액, 고용일 조회
SELECT EMP_NAME 이름, SALARY "급여", SALARY *(1+BONUS)*12 - SALARY*12*0.03 AS 실수령액, HIRE_DATE AS "고용일"
FROM EMPLOYEE
WHERE SALARY *(1+BONUS)*12 - SALARY*12*0.03 >= 5000000;
-- 컬럼 산술연산으로 뽑아낸 값을 조건식의 기준 데이터에 사용가능

 

 

 

 

 

728x90
반응형
728x90

 

ESCAPE 식별자

escape 식별자로 like 연산자를 사용하여 '%' 및 '_' 가 포함된 문자 패턴을 검색할 수 있다.

 

컬럼명 != '김%' 과 컬럼명 LIKE ‘김%’의 차이

= 혹은 != '김%'으로 검색하면 '김%' 데이터자체를 검색

LIKE '김%' 뒤에 어떤게 오든 상관없다. LIKE와 사용하는 % _ 는 와일드카드 적용받는다

 

SELECT EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';
-- WHERE NOT PHONE LIKE '010%';

 

IS NULL

컬럼값이 NULL이냐

WHERE BONUS IS NULL;

IS NOT NULL

컬럼값이 NULL이 아니냐

  - NOT의 위치는 컬럼명 앞도 가능

WHERE BONUS IS NOT NULL;

 

IN

목록에 일치하는 값이 있으면 TRUE가 되어 값 반환

장점 : 코드가 상당히 짧아진다

SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
-- WHERE DEPT_CODE = 'D6' OR DEPT_CODE = 'D9';
WHERE DEPT_CODE IN ('D6','D9');

 

연결 연산자 : ||

문장으로 연결해서 쓰고 싶을 경우 필요

 

-- EMPLOYEE테이블에서 ' "사원명"의 월급은 "급여"원입니다' 형식으로 조회
SELECT EMP_NAME ||'의 월급은'|| SALARY||'원입니다'
FROM EMPLOYEE;

 

--  ESCAPE 식별자

-- EMPLOYEE테이블에서 김씨 성이 아닌 직원의 사번, 이름, 고용일 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE
FROM EMPLOYEE
--WHERE EMP_NAME NOT LIKE '김%';
WHERE NOT EMP_NAME LIKE '김%';


--WHERE NOT EMP_NAME LIKE '김%';
-- NOT 순서 : 해당 컬럼명 앞뒤 둘 다 가능

/*
WHERE EMP_NAME != '김%'; 
 = 혹은 != '김%'으로 검색하면 '김%' 데이터자체를 검색
LIKE '김%' 뒤에 어떤게 오든 상관없다
LIKE와 사용하는 % _ 는 와일드카드 적용받는다    
    LIKE는 문자에 대한 패턴 검색하는 것

!= '김%'에서는 이름이 김%인 사람을 찾는 것(리터럴 김% 데이터를 찾는 것)
    여기서 %는 와일드카드로 적용이 되지 않고 그냥 순수 기호 %인 것

*/

-----------실습문제-----------
--1.EMPLOYEE 테이블에서 이름 끝이 '연'으로 끝나는 사원 이름 조회
--2.EMPLOYEE 테이블에서 전화번호 처음 세자리가 010이 아닌 사원의 이름, 전화번호 조회
--3.EMPLOYEE 테이블에서 메일주소 _의 앞이 4자이면서 DEPT_CODE가 D9 또는 D6이고
--  고용일이 90/01/01 ~ 00/12/01이고, 급여가 2700000만 이상인 사원의 전체 정보 조회

SELECT EMP_NAME
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%연';

SELECT EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';

SELECT *
FROM EMPLOYEE
WHERE EMAIL LIKE '____!_%' ESCAPE '!'
        AND (DEPT_CODE = 'D9' OR DEPT_CODE = 'D6')
        -- AND (HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '00/12/01')
        AND HIRE_DATE BETWEEN '90/01/01' AND '00/12/01'
        AND SALARY >= 2700000;

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

-- IS NULL
-- IS NOT NULL
-- 컬럼값이 NULL이냐
-- 컬럼값이 NULL이 아니냐

--EMPLOYEE 테이블에서 보너스를 받지 않는 사원의 사번, 이름, 급여, 보너스 조회
SELECT EMP_ID, EMP_NAME,SALARY,BONUS
FROM EMPLOYEE
WHERE BONUS IS NULL;


--WHERE BONUS = NULL; 값 안나옴
--WHERE BONUS = (null); 값 안나옴

--EMPLOYEE 테이블에서 보너스를 받는 사원의 사번, 이름, 급여, 보너스 조회
SELECT EMP_ID, EMP_NAME,SALARY,BONUS
FROM EMPLOYEE
WHERE BONUS IS NOT NULL;
WHERE NOT BONUS IS NULL;


-- WHERE NOT BONUS IS NULL; 
-- NOT은 컬렴명 앞에 붙어도 가능

--WHERE BONUS NOT LIKE '%(null)%';


-- EMPLOYEE 테이블에서 관리자도 없고 부서 배치도 받지 않은 직원의 이름, 관리자, 부서코드 조회
-- EMPLOYEE 테이블에서 부서 배치를 받지 않았지만 보너스를 지급받는 직원의 이름,  보너스, 부서코드 조회
SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;


SELECT EMP_NAME, BONUS, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE IS NULL AND BONUS IS NOT NULL;

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

--IN
-- 목록에 일치하는 값이 있으면 TRUE가 되어 값 반환
-- 목록에 일치하는 값이 있으면 TRUE를 반환


-- D6부서와 D9부서원들의 이름, 부서코드, 급여 조회
-- 직급코드가 J1, J2, J3, J4인 사람들의 이름, 직급코드, 급여 조회
SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' OR DEPT_CODE = 'D9';

SELECT EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
--WHERE JOB_CODE = 'J1' OR JOB_CODE = 'J2' OR JOB_CODE = 'J3' OR JOB_CODE =  'J4';
WHERE JOB_CODE IN ('J1','J2','J3','J4');

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- 연결 연산자 ||
-- 자바에서의 or논리연산자의 기호가 SQL에서는 연결연산자
-- EMPLOYEE테이블에서 사번, 이름, 급여를 연결해서 조회 (EX. 200선동일8000000)

SELECT EMP_ID || EMP_NAME || SALARY
FROM EMPLOYEE;
SELECT EMP_ID || EMP_NAME || SALARY 전체결과
FROM EMPLOYEE;

-- EMPLOYEE테이블에서 ' "사원명"의 월급은 "급여"원입니다' 형식으로 조회
SELECT EMP_NAME ||'의 월급은'|| SALARY||'원입니다'
FROM EMPLOYEE;

 

 

 

 

 

728x90
반응형
728x90

논리연산자

자바 : && ||

오라클 : AND OR

문자 그대로 AND, OR로 사용

 

※ 날짜를 기준으로 조건식을 쓴다면 ' '로 감싸줘야한다

기준일보다 작은게 빠른 것. 오늘보다 내일이 더 큰 숫자

-- EMPLOYEE 테이블에서 부서코드가 D6이고 급여를 3000000보다 많이 받는 직원의 이름, 부서코드, 급여 조회
SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' AND SALARY > 3000000;

-- EMPLOYEE 테이블에서 부섴드가 D6이거나 급여를 3000000보다 많이 받는 직원의 이름,부서코드, 급여조회
SELECT EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' OR SALARY > 3000000;

 

 

OR AND 연산 우선순위

자바나 SQL이나 OR AND 연산순서는 AND가 우선순위로 먼저 연산

OR를 먼저 연산하고 싶다면 소괄호를 쳐줄 것

 

BETWEEN

~이상 ~이하

-- EMPLOYEE 테이블에서 급여를 3500000이상 6000000이하를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
WHERE SALARY BETWEEN 3500000 AND 6000000;

 

초과 미만은?

not between

-- 반대로 급여를 3500000미만 6000000초과를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
-- WHERE SALARY < 3500000 OR SALARY > 6000000;
WHERE SALARY NOT BETWEEN 3500000 AND 6000000;
WHERE NOT SALARY BETWEEN 3500000 AND 6000000;
-- NOT 위치 둘 다 가능

 

 

LIKE

비교하려는 값이 특정 패턴을 만족시키는지 조회

ex) 이멜에 i가 들어가는 것을 조회, 이름이 김씨가 들어간 사람들 조회

--EMPLOYEE 테이블에서 이름이 '하'가 포함된 직원의 이름, 주민번호, 부서코드 조회
SELECT EMP_NAME, EMP_NO, DEPT_CODE
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%하%';

 

와일드카드 2종류 :  _  %

_ : 1글자 % : 0글자 이상

ex) '' (한글자) '__' (두글자) ***'__***' (세글자)

 

  • '글자%' : 글자로 시작하는 값

글자 뒤로 뭐가와도 ok

ex) 글자최고, 글자(공백), 글자왕, 글자

 

  • '%글자' : 글자로 끝나는 값

글자 앞에 뭐가와도 ok

ex) 먹글자, 한글은 글자, (공백)글자

 

  • '글%자' : 글로 시작해서 자로 끝나는 값

글과 자 사이 뭐가와도 ok

ex)글씨를 잘쓰자, 글자, 글과자, 글(공백)자

 

  • '%글자%' : 글자가 포함되어있는 값

ex) 한글자값, 먹글자, 글자, 한두글자

 

-- 논리 연산자 AND OR
-- EMPLOYEE 테이블에서 부서코드가 D6이고 급여를 3000000보다 많이 받는 직원의 이름, 부서코드, 급여 조회
SELECT EMP_NAME, DEPT_CODE,SALARY  
FROM EMPLOYEE
WHERE DEPT_CODE = 'D6' AND SALARY > 3000000;


-- EMPLOYEE 테이블에서 부섴드가 D6이거나 급여를 3000000보다 많이 받는 직원의 이름,부서코드, 급여조회
SELECT  EMP_NAME, DEPT_CODE,SALARY 
FROM EMPLOYEE
WHERE   DEPT_CODE = 'D6' OR SALARY > 3000000;




-- 1.EMPLOYEE 테이블에서 월급이 4000000이상이고 JOB_CODE가 J2인 사원의 전체 내용 조회
-- 2.EMPLOYEE 테이블에 DEPT_CODE가 D9이거나 D5인 사원 중에 고용일이 02년 1월 1일보다 빠른 사원의
--   이름, 부서코드, 고용일 조회
SELECT *  
FROM EMPLOYEE
WHERE SALARY >= 4000000 AND JOB_CODE ='J2';

SELECT EMP_NAME, DEPT_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9' OR HIRE_DATE < '02/01/01';



-- 이 코드는 틀린 코드
-- 기준일보다 작은게 빠른 것. 오늘보다 내일이 더 큰 숫자
-- 날짜를 기준으로 조건식을 쓴다면 ''로 감싸줘야한다
-- 자바나 SQL이나 OR AND는 AND가 우선순위로 먼저 연산
-- OR를 먼저 연산하고 싶다면 소괄호를 쳐줄 것





------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------


-- BETWEEN AND
-- ~이상 ~이하

-- EMPLOYEE 테이블에서 급여를 3500000이상 6000000이하를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE  
WHERE SALARY >= 3500000 AND SALARY <= 6000000;

SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE 
WHERE SALARY BETWEEN 3500000 AND 6000000;

-- 반대로 급여를 3500000미만 6000000초과를 받는 사원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE
FROM EMPLOYEE
--WHERE SALARY < 3500000 OR SALARY > 6000000; 
--WHERE SALARY NOT BETWEEN 3500000 AND 6000000;
WHERE NOT SALARY BETWEEN 3500000 AND 6000000;

-------실습문제-------
-- 1.EMPLOYEE 테이블에 고용일이 90/01/01 ~ 01/01/01인 사원의 전체 내용을 조회
-- 시간의축을 가로선상에 놓고 보면 시간과 연산자 사용계산이 쉬워짐

SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';

SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE BETWEEN '90/01/01' AND  '01/01/01';

-- WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';




------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

/*
-- LIKE
비교하려는 값이 특정 패턴을 만족시키는지 조회
ex) 이멜에 i가 들어가는 것을 조회, 이름이 김씨가 들어간 사람들 조회

와일드카드 2종류
 _ : 1글자
 % : 0글자 이상

ex)
'_' (한글자)
'__' (두글자)
'___' (세글자)

 '글자%' : 글자로 시작하는 값
    글자 뒤로 뭐가와도 ok
    ex) 글자최고, 글자(공백), 글자왕, 글자
 '%글자' : 글자로 끝나는 값
    글자 앞에 뭐가와도 ok
    ex) 먹글자, 한글은 글자, (공백)글자
 '글%자' : 글로 시작해서 자로 끝나는 값
    글과 자 사이 뭐가와도 ok
    ex)글씨를 잘쓰자, 글자, 글과자, 글(공백)자
 '%글자%' : 글자가 포함되어있는 값
        ex) 한글자값, 먹글자, 글자, 한두글자

*/

--EMPLOYEE 테이블에서 성이 전씨인 사원의 사번, 이름, 고용일 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE
FROM EMPLOYEE
WHERE EMP_NAME LIKE '전%';
-- WHERE EMP_NAME LIKE '전__';
-- 도 가능하나 이름이 세글자인 사람들만 가능해서 이름이 두글자나 네글자이상이면 정확도가 떨어짐



--EMPLOYEE 테이블에서 이름이 '하'가 포함된 직원의 이름, 주민번호, 부서코드 조회
SELECT EMP_NAME, EMP_NO, DEPT_CODE
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%하%';


--EMPLOYEE 테이블에 전화번호 4번째 자리가 9로 시작하는 사원의 사번, 이름, 전화번호 조회
-- 전번 양식 : 01012345678
-- 01X 세자리 + 9로 시작하는 네번지째 자릿수
SELECT EMP_ID, EMP_NAME, PHONE
FROM EMPLOYEE
WHERE PHONE LIKE '___9%';

--EMPLOYEE 테이블에서 이메일 중 _의 앞 글자가 3자리인 이메일 주소를 가진 사원의 사번의 사번, 이름, 이메일 주소 조회
SELECT EMP_ID, EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___ _%' ESCAPE ' ';
D
--WHERE EMAIL LIKE '___%'; -- 언더바_가 들어간 이메일 출력. 앞글자 2개도 4개 전부 출력



-- ESCAPE의 기준이 되는 코드는 ' '안에서 설정 가능? YES
-- ESCAPE의 ' '안에 어떤 코드이던 들어가서 설정 가능?
/*
LIKE를 쓸 때 패턴!
와일드카드 : _ %
각각 한글자,와 0글자 이상을 나타내는 와일드 카드

세글자 자릿수 언더바 3개 + 검색하고자 하는 데이터로의 언더바 1개 = 총4개의 언더바
검색하고자 하는 패턴의 문자와 와일드 카드가 일치할 경우에는 패턴과 와일드 카드를 구분하지 못하기 때문에
ESCAPE OPTION을 통해 구분해준다
 - 패턴(데이터)으로 쓸 것 앞에 구분기호 사용

*/

 

 

 

 

728x90
반응형
728x90

 

SELECT 컬럼명 -- 조회하고자 하는 컬럼명 기술
FROM 테이블명 -- 조회하고자 하는 컬림이 포함된 테이블명 기술
WHERE 조건식; -- 행을 선택하는 조건 기술, 조건을 만족하는 행만 반환
                     -- 조건식 복수로 붙여서 사용가능. 복수라도 WHERE절 한개만 기술



비교연산자

>, <, >=, <=, = ,!= 

크다, 작다, 크거나 같다
같다 : =
같지않다 : != , ^= , <>

 

컬럼 별칭

컬럼명  AS 별칭 / 컬럼명 AS “별칭” / 컬럼명 별칭 / 컬럼명 “별칭”

별칭 : "" 

 

리터럴(literal)

값 자체

싱글쿼테이션( ' ' )

오라클에서는 문자,문자열,데이트 상관없이 다 싱글쿼테이션(’ ‘)으로 감싸준다



 

 

-- 컬럼 별칭
-- 컬럼명  AS 별칭 / 컬럼명 AS “별칭” / 컬럼명 별칭 / 컬럼명 “별칭”



/*
리터럴(literal)
값 자체 ‘ ‘

오라클에서는 문자,문자열,데이트 상관없이 다 싱글쿼테이션(’ ‘)으로 감싸준다
데이터 타입에 상관없이 별칭(””) 외에는 다 싱글쿼테이션으로 감싼다
*/ 

-- EMPLOYEE 테이블에서 직원의 직원 번호, 사원명, 급여, 단위 조회
SELECT EMP_NO, EMP_NAME, SALARY, '원' "단위 : 원"
FROM EMPLOYEE;
SELECT EMP_NO, EMP_NAME, SALARY, '@' "원"
FROM EMPLOYEE;


-- 별칭 : "" 
-- 리터럴을 싱글쿼테이션으로 처리한다 : ' '
-- '원'이라는 컬럼을 보여주고 싶지않으면 더블쿼테이션""으로 단위써주자



-- EMPLOYEE테이블에서 직원의 직급 코드 조회
SELECT EMP_ID, '직급코드' AS 직급코드
FROM EMPLOYEE;

SELECT EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE 'b%';
-- 결과 : 방명수 bang ns@kh.kr


-- 결과 : 없음
-- 리터럴은 대소문자 철저히 구별하기에 대문자 BANG으로 시작하는 EMAIL이 없어서 안나온 것



-- EMPLOYEE 테이블에서 직원의 부서 코드를 중복 없이 조회
SELECT DISTINCT JOB_CODE
FROM EMPLOYEE;

-- DISTINCT는 한번만 쓸 수 있다
--SELECT DISTINCT DEPT_CODE, DISTINCT DEPT_CODE -- error
--FROM EMPLOYEE;
SELECT DISTINCT DEPT_CODE, JOB_CODE -- 콤마로 두 컬럼을 묶으면 두 컬럼의 조건이  
FROM EMPLOYEE;                      -- AND조건으로 교집합 된 것만 중복 제거한다



/*
SELECT 컬럼명 -- 조회하고자 하는 컬럼명 기술
FROM 테이블명 -- 조회하고자 하는 컬림이 포함된 테이블명 기술
WHERE 조건식; -- 행을 선택하는 조건 기술, 조건을 만족하는 행만 반환
             -- 조건식 복수로 붙여서 사용가능. 복수라도 WHERE절 한개만 기술


--비교연산자
>, <, >=, <=, = ,!= 

크다, 작다, 크거나 같다
같다 : =
같지않다 : != , ^= , <>
*/

--EMPLOYEE테이블에서 부서코드가 'D9'인 직원의 이름, 부서코드 조회
SELECT EMP_NAME, DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9';


-- '' 없이 D9만 쓰면 컬럼으로 인지하게 됨
-- 'd9'라고 써도 안됨. 리터럴은 대소문자 구분



--급여가 4000000이상인 직원의 이름, 급여 조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY >= 4000000;




-- EMPLOYEE테이블에서 부서코드가 D9이 아닌 사원의 사번, 이름, 부서코드조회
SELECT EMP_NO, EMP_NAME, DEPT_CODE
FROM EMPLOYEE
--WHERE DEPT_CODE != 'D9';
WHERE DEPT_CODE <> 'D9';
WHERE DEPT_CODE ^= 'D9';


-- EMPLOYEE 테이블에서 퇴사 여부가 N인 직원을 조회하고 근무 여부를 재직중으로 표시
-- 사번,이름, 고용일, 근무여부 조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE, '재직중' "근무여부"
FROM EMPLOYEE
WHERE ENT_YN = 'N';

 

 

 

 

728x90
반응형

+ Recent posts