디지털 컨버전스/Oracle

[Oracle] Alias, self join, set operator(union, union all, intersect, minus), sequence , DML(delete , update)

gimyeondong 2020. 3. 19. 10:07

 

JOIN

Natural JOIN - Cartesian Product

Inner JOIN - 조건을 충족하는 결과들만의 집합

Outer JOIN - 조건이 충족되지 않아도 일단 모두 출력하는 집합

 


조인할 테이블들의 컬럼명이 같을 경우 조인하기 곤란
테이블의 이름 붙여놓기 (as)

 

-- 조인할 테이블들의 컬럼명이 같으면 조인하기 곤란 
-- employee의 job_code, job의 job_code 조인

select 
    *
from employee, job 
    where job_code = job_code;
    
--00918. 00000 -  "column ambiguously defined"
-- 컬럼이 모호하게 정의되었습니다.
-- 테이블에 별명 붙여놓기 (as)

select 
    * 
from employee emp, job j 
    where emp.job_code = j.job_code;
    
select 
    emp_name, job_name, emp.job_code 
from employee emp, job j 
    where emp.job_code = j.job_code;

self join

 

-- 한 행씩 봤을때 자기 자신이 자신의 직속상사일수 없음

select emp_id , emp_name, Manager_id from employee
    where emp_id = manager_id;
-- self join도 두 테이블이라고 생각하고 구성

select e1.emp_id, e1.emp_name, e2.emp_name
    from employee e1 , employee e2
    where e1.manager_id = e2.emp_id;

테이블 3개 연결

 

 

select
    emp_name,
    dept_title
from employee e, department d
    where e.dept_code = d.dept_id;
-- 자바의 3중 for문과 유사한 형태

select
    e.emp_name
    d.dept_title
    d.location_id
from employee e, department d, location l
    where
        e.dept_code = d.dept_id and
        d.location_id = l.local_code;

select * from employee;
select * from department;
select * from location;
select * from national;

select
    e.emp_name,
    d.dept_title,
    n.national_name
from employee e, department d, location l, national n
    where
        e.dept_code = d.dept_id and
        d.location_id = l.local_code and
        l.national_code = n.national_code;

--ansi 표준

select
    e.emp_name,
    d.dept_title,
    n.national_name
from 
    employee e join department d on  e.dept_code = d.dept_id
    join location l on d.location_id = l.local_code
    join national n on l.national_code = n.national_code;

--outer join

select
    e.emp_name,
    d.dept_title,
    n.national_name
from employee e, department d, location l, national n
    where
        e.dept_code = d.dept_id(+) and
        d.location_id = l.local_code(+) and
        l.national_code = n.national_code(+);

--각 사원들의 이름 / 나이 / 부서명 / 직급명을 출력하세요.

select
    e.emp_name "이름",
    extract(year from sysdate)-(decode(substr(e.emp_no,8,1),1,1900,2,1900,3,2000,4,2000)+substr(e.emp_no,1,2)) "나이",
    d.dept_title "부서명",
    j.job_name "직급명"
from employee e, department d, job j
    where
        e.dept_code = d.dept_id(+) and
        e.job_code = j.job_code(+);


-- 1. 2030년 12월 25일의 요일을 출력하시오

select
    to_char(to_date(20301225),'day')
from
    dual;
-- 2. 주민번호가 1970년대 생이면서 성별이 여자이고,
-- 성이 전씨인 직원들의 사원명, 주민번호, 부서명, 직급명을 조회하세요.

select
    e.emp_name "사원명",
    e.emp_no "주민번호",
    d.dept_title "부서명",
    j.job_name "직급명"
from employee e, department d, job j
    where
        e.dept_code = d.dept_id(+) and
        e.job_code = j.job_code(+);
-- 3. 이름에 '형' 자가 들어가는 직원들의 사번, 사원명, 부서명을 조회하세요.

select
    e.emp_id "사번",
    e.emp_name "사원명",
    d.dept_title "부서명"
from employee e, department d
    where
        e.emp_name like '%형%' and
        e.dept_code = d.dept_id(+);
-- 4. 해외영업부에 근무하는 사원명, 직급명, 부서코드, 부서명을 조회하세요.

select
    e.emp_name "사원명",
    j.job_name "직급명",
    e.dept_code "부서코드",
    d.dept_title "부서명"
from employee e, job j, department d
    where 
        d.dept_title like '해외영업%' and
        e.job_code = j.job_code and
        e.dept_code = d.dept_id;
-- 5. 보너스포인트를 받는 직원들의 
--사원명, 보너스포인트, 부서명, 근무지역명(나라이름)을 조회하세요

select
    e.emp_name "사원명",
    e.bonus "보너스포인트",
    d.dept_title "부서명",
    n.national_name "근무지역명"
from employee e, department d , location l, national n
    where
        e.bonus is not null and
        e.dept_code = d.dept_id and
        d.location_id = l.local_code and
        l.national_code = n.national_code;
-- 6. 부서코드가 D2인 직원들의
-- 사원명, 직급명, 부서명, 근무지역명을 조회하세요.

select
    e.emp_name "사원명",
    j.job_name "직급명",
    d.dept_title "부서명",
    n.national_name "근무지역명"
from employee e, job j, department d, location l,national n
    where
        e.dept_code = 'D2' and
        e.job_code = j.job_code and
        e.dept_code = d.dept_id and
        d.location_id = l.local_code and
        l.national_code = n.national_code;
-- 7. 급여등급테이블의 최대급여 (MAX_SAL - 500000)보다 많이 받는 직원들의
-- 사원명, 직급명, 급여, 연봉을 죄회하세요.

select
    e.emp_name "사원명",
    j.job_name "직급명",
    e.salary"급여",
    e.salary*12 "연봉"
from employee e, job j , SAL_GRADE s
    where
        e.salary*12>(s.max_sal - 5000000) and
        e.job_code = j.job_code and
        e.sal_level = s.sal_level ;
-- 8. 한국(KO)과 일본(JP)에 근무하는 직원들의
-- 사원명, 부서명, 지역명, 국가명을 조회하세요.

select
    e.emp_name "사원명",
    d.dept_title "부서명",
    l.local_name "지역명",
    n.national_name "국가명"
from employee e, department d, location l, national n
    where
        n. national_code in ('KO','JP') and
        e.dept_code = d.dept_id and
        d.location_id =l.local_code and
        l.national_code = n.national_code;
-- 9. 같은 부서에 근무하는 직원들의
-- 사원명, 부서명, 동료이름을 조회하세요. (self join 사용)
-- ex) 홍길동 기술지원부 김철일
--     홍길동 기술지원부 김철이
--     홍길동 기술지원부 김철삼

select
    e1.emp_name "사원명",
    d.dept_title "부서명",
    e2.emp_name "동료이름"
from employee e1, department d, employee e2
    where
        e1.dept_code = d. dept_id and
        e1.emp_name !=e2.emp_name
    order by 1;
-- 10. 보너스포인트가 없는 직원들 중에서 직급이 차장과 사원인 직원들의
-- 사원명, 직급명, 급여를 조회하시오. 단, join과 IN 사용할 것

select
    e.emp_name "사원명",
    j.job_name "직급명",
    e.salary "급여"
from employee e, job j
    where
        e.bonus is null and
        j.job_name in ('차장','사원') and
        e.job_code=j.job_code;
-- 11. 재직중인 직원과 퇴사한 직원의 수를 조회하시오.
-- 재직여부 인원수
-- 퇴사      1
-- 재직      22

select
   decode(ent_yn,'N','재직','Y','퇴사') "재직여부",
   count(*) "인원수"
from employee
   group by decode(ent_yn,'N','재직','Y','퇴사');

-- DQL
-- set operator
-- sub query (중요한 내용이지만 23일 시험 내용에서는 빠짐)


set operator (집합 연산자)
UNION / UNION ALL / INTERSECT / MINUS

 

select * from employee
union 
select * from department;
--"query block has incorrect number of result columns"
--컬럼 개수가 같고 그 자료형이 상호호환 되어야 함
--오라클에서 문자열을 숫자로 호환

select '10'+5 from dual;
--15
-- 상호호환

select emp_id, emp_name, dept_code from employee
union 
select * from department;

--상호호환 안됨

select emp_id, salary, dept_code from employee
union 
select * from department;

--"expression must have same datatype as corresponding expression"

create table tempA(
    temp_col varchar(10)
);
create table tempB(
    temp_col varchar(10)
);

insert into tempA values(1);
insert into tempA values(2);
insert into tempA values(3);
select * from tempA;

insert into tempB values(2);
insert into tempB values(3);
insert into tempB values(4);
select * from tempB;

union : 중복제거하여 합쳐준다.

-- union : 중복제거하여 합쳐준다.

select * from tempA
union
select * from tempB;

union : 중복제거


union all : 중복제거 없이 다 합쳐준다.

union all : 중복제거 없이 다 합쳐준다.

select * from tempA
union all
select * from tempB;

union : 중복포함


intersect : 겹치는 부분만 보여준다.

-- intersect : 겹치는 부분만 보여준다.

select * from tempA
intersect
select * from tempB;

intersect 

 


minus : 결과값을 제외

--minus : 결과값을 제외

select * from tempA
minus
select * from tempB;

-- 2, 3은 겹치므로 제외, 4는 원래 없었으니 없음

minus


sequence : 순서

값의 순서를 기억하는 객체

 

create table cafe(
    pid number primary key,
    pname varchar(30) not null,
    price number default 0 not null
);
insert into cafe values(1001,'Americano',2000);
insert into cafe values(1002,'Cafe Latte',2500);
insert into cafe values(1003,'Cafe Mocha',3000);
select * from cafe;
--시퀀스 : 값의 순서를 기억하는 객체
-- sequence : 순서

create sequence cafe_seq
start with 1004
increment by 1
nomaxvalue
nocache;
--nocache를 주지 않으면 오라클 시스템이 값을 변경

select sequence_name from user_sequences;
--딕셔너리 : 내린 명령을 기억하는 내장 테이블

insert into cafe values(cafe_seq.nextval,'Caramel macchiato',3500);

1004번이 알아서 입력되었다.


DML : 테이블을 대상으로 데이터 수정

delete : 데이터 지우기

 

--sequence 값을 줄이고 싶을때 : 인위적으로 건드리는 문법 없음
--1. 새로 만들기
--2. increment by를 -로 변경

--DDl 객체 지우기 ; drop
--하나만 지우기 (데이터 DML : delete)
--delete from cafe 는 모든 행을 지우므로, where절로 지울 행 정해주기
delete from cafe where pid=1004;

select * from cafe;

pid = 1004인 행 삭제


update : 변경하기

 

--DML : 테이블을 대상으로 데이터 수정
--DML : update

update cafe 
    set price=3500, pname='Hot choco'
where pid =1003;

select * from cafe;