수업/DB

230615 (JOIN, UNION)

보더96 2023. 6. 15. 16:44

정규화를 잘해야 메모리 최적화가 된다.

 

JOIN :  여러테이블의 자료를 같이 출력할때 JOIN이 편리하다.

SUBQUERY :  SELECT 해야할것들이 한테이블에 있을경우 SUBQUERY가 편리하다.

 

ON 절 : 직접적인 관계가 있어야함 (같은 명칭이 있어야한다)

ex : 각테이블에 employee.department_id = department.department_id 경우 ON절 가능

 

IN 절 : 

 

 

JOIN : 결합,  여러 테이블의 컬럼을 결합,  

 

 

INNER JOIN  -->  

OUTTER JOIN  -->  기준이 되는 테이블의 모든 정보를 출력

 

 

 

ㅡㅡ사원의 사번, 이름, 부서번호, 부서명을 출력하시오

SELECT employee_id, department_id

FROM employees;           107건

 

SELECT department_id, department_name

FROM departments;         27건

 

ㅡㅡ카티션프로덕트 : 조건없은조인  (밑 내용은 오라클용 JOIN)

SELECT employee_id, department_name

FROM employee, departments;  -->  107(employees) *27(departments) 값이 나오게된다.

카티션프로덕트 : 조건없은조인

 

 

표준(ANSI) (INNER가 생략어되어있다) JOIN 법

표준(ANSI) JOIN 법

SELECT

FROM  테이블1  JOIN  테이블2  ON  (테이블1.컬럼 = 테이블2.컬럼)

 

SELECT

FROM  테이블1 NATURAL JOIN  테이블2     --->   안하는게 좋음 (위험!)

컬럼명이 같은 경우 NATURAL JOIN  축약하여 사용

 

SELECT

FROM  테이블1 JOIN  테이블2  USING  컬럼   --->   비추천!

 

 

 

 

 

 

JOIN ON         (★중요★)

ㅡㅡ사원의 사번, 이름, 부서번호, 부서명을 출력하시오 (JOIN 예시!!)ㅡㅡ

SELECT employee_id, employees . department_id , department_name

FROM employees

JOIN departments ON (employees . department_id  =  departments .  department_id);

 

ㅡㅡ사원의 사번, 이름, 부서번호, 부서명, 직무번호, 직무명을 출력하시오ㅡㅡ

SELECT employee_id, employees . department_id , department_name, job_title, jobs_id

FROM employees

JOIN departments ON (employees . department_id  =  departments .  department_id)

JOIN jobs ON (employees.job_id =jobs. job_id);

 

ㅡㅡ사원의 사번, 이름, 부서번호, 부서명을 출력하시오 (JOIN 별칭주기!!)ㅡㅡ

SELECT employee_id, e . department_id , department_name

FROM employees e

JOIN departments d ON (e . department_id  =  d . department_id);

 

ㅡㅡ사원의 사번, 이름, 부서번호, 부서명, 직무번호, 직무명을 출력하시오(JOIN 별칭주기!!)ㅡㅡ

                  jobs  -  j,     departments  -  d,      employees  -  e  로 별칭주기

SELECT employee_id, e. department_id , department_name, j.job_title, j.job_id
FROM employees e
JOIN departments d ON (e . department_id  =  d .  department_id)
JOIN jobs j ON (e . job_id = j . job_id);

 

ㅡㅡ국가의 국가번호 (country_id), 국가이름(country_name), 도시명(city)을 출력하시오ㅡㅡ

SELECT * FROM countries;   --25건

SELECT * FROM locations;    --23건

SELECT l.country_id, c.country_name, l.city

FROM locations l

JOIN countries c ON (l.country_id= c.country_id);

 

 

 

NATURAL JOIN

ㅡㅡ사원의 사번, 직무번호, 직무명을 출력하시오.ㅡㅡ

SELECT employees_id, jobs.job_id, jobs.job_title

FROM employees

JOIN jobs ON (employees.job_id = jobs.job_id);

 

컬럼명이 같은 경우 NATURAL JOIN  축약하여 사용

SELECT employee_id, job_id, job_title

FROM employees NATURAL JOIN jobs;

 

ㅡㅡ사원의 사번, 부서번호, 부서명을 출력하시오.ㅡㅡ

SELECT employee_id, departments.department_id, departments.department_name
FROM employees JOIN departments ON (employees.department_id = departments.department_id);

 

SELECT employee_id, departments.department_id, departments.department_name
FROM employees NATURAL JOIN departments;          (X)        -----32건출력

 

NATURAL 사용할 경우 DEPARTMENT ID와 MANAGER ID 가 같은것을 찾게된다.

SELECT employee_id, departments.department_id, department_name
FROM employees JOIN departments
ON (employees.department_id = departments.department_id 
AND employees.manager_id = departments.manager_id);

                    ㅡㅡ위의 NATURAL JOIN과 같은뜻이다.       -32건출력

 

 

 

JOIN USING

ㅡㅡ사원의 사번, 직무번호, 직무명을 출력하시오ㅡㅡ 107건

SELECT employee_id, jobs.job_id, jobs.job_title

FROM employeeㄴ JOIN jobs ON (employees.job_id = jobs.job_id);

 

ON   --->  USING으로 변환했을 경우

SELECT employee_id, jobs.job_id, jobs.job_title

FROM employees JOIN jobs USING (job_id);

 

 

ㅡㅡ사원의 사번, 이름, 부서번호, 부서명을 출력하시오 ㅡㅡ  106건

SELECT employee_id, employees . department_id , department_name

FROM employees JOIN departments ON (employees . department_id  =  departments .  department_id);

 

ON   --->  USING으로 변환했을 경우

SELECT employee_id,  department_id , department_name

FROM employees JOIN departments USING (department_id);

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

OUTER JOIN

ㅡㅡ전체사원의 사번, 이름, 부서번호, 부서명을 출력하시오 --107건

SELECT employee_id, employees.department_id, department_name

FROM employees LEFT OUTER JOIN departments

ON (employees.department_id = departments.department_id);

 

(LEFT쓰는 이유 : 왼쪽테이블이 기준이된다. RIGHT쓰면 오른쪽테이블이 기준이된다!!)

대부분 기준이 되는 테이블은 왼쪽에다가 쓴다

 

ㅡㅡ국가의 국가번호 (country_id), 국가이름(country_name), 도시명(city)을 출력하시오ㅡㅡ

ㅡㅡ도시가 등록안된 국가도 출력한다

SELECT * FROM countries;   --25건        (국가안에 도시정보는 없을수 있다)

SELECT * FROM locations;    --23건

 

 

countries를 기준을 삼으니깐 LEFT로 적어준다!

SELECT country_id, country_name, city
FROM countries  LEFT  JOIN  locations  USING  (country_id);

 

countries  와  countries   자리 바꾸면 RIGHT로 변경

SELECT country_id, country_name, city
FROM locations  RIGHT  JOIN  countries  USING  (country_id);

 

 

ㅡㅡ모든사원의 사번, 부서번호, 부서명을 출력하시오

ㅡㅡ부서없는 사원도 출력하고 ,  사원이 없는 부서들도 출력 한다.

ㅡㅡ부서없는 사원 출력

SELECT employee_id, e.department_id, department_name
FROM employees e LEFT JOIN departments d
ON(e.department_id = d.department_id);  --부서없는 사원도 출력 --- 107건

ㅡㅡ사원이 없는 부서 출력

SELECT employee_id, e.department_id, department_name
FROM employees e RIGHT JOIN departments d
ON(e.department_id = d.department_id);  --사원없는 부서도 출력도 출력 ---122건

 

FULL JOIN  ---  123건

SELECT employee_id, e.department_id, department_name
FROM employees e FULL JOIN departments d
ON(e.department_id = d.department_id);  -부서없는 사원+사원이없는부서 -- 123건

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

SELF JOIN (특이한 관계선,자기참조관)  --  자기가 자기를 참조하는 관계

employee_id 와 manager_id는 자기참조관계이다.

테이블은 하나인데 논리적으로 분리해 2개로 한다.

하나는 사원 하나는 관리자용

테이블은 하나인데 논리적으로 분리해 2개로 한다.            하나는 사원 하나는 관리자용!

한 사원은 한 관리자에 의해 관리된다.

한 사원을 관리하는 관리자는 한명이다.

한 사람을 관리하는 또 다른 관리자는 없을수도 있다.

한 관리자가 관리하는 사원은 없거나 여러명일수도 있다. (스키마 양쪽이 동그라미)

한 사원이 관리하는 관리자는 없거나 여러명일수도 있다. (스키마 양쪽이 동그라미)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

 

SELF JOIN

사원의 사번, 이름, 관리자번호, 관리자이름을 출력하시오

SELECT e.employee_id , e.first_name , m.manager_id , m.first_name 
FROM employees  e  JOIN employees  m  ON ( e.manager_id = m.employee_id );

 

ㅡㅡ사원의 사번, 이름, 사원소속부서, 관리자번호, 관리자이름, 관리자소속부서 를 출력하시오

ㅡ사원부서와 관리자부서가 다른사원들만 출력하시오.

 

SELECT e.employee_id 사번, e.first_name 이름, e.department_id 소속부서, m.manager_id, m.first_name 관리자이름, m.department_id 관리자소속부서
FROM employees e JOIN employees m ON( e.manager_id = m.employee_id)
WHERE e.department_id <> m.department_id;

 

ㅡㅡ사원의 사번, 이름, 사원급여, 관리자번호, 관리자이름, 관리자급여 를 출력하시오

ㅡ사원의 급여가 관리자급여보다 많은 사원들만 출력한다.

SELECT e.employee_id 사번, e.first_name 이름, e.salary 사원급여, m.manager_id 관리자번호, m.first_name 관리자이름,  m.salary 관리자급여

FROM employees e JOIN employees m ON(e.manager_id = m. employee_id)

WHERE e.salary > m. salary;

 

 

JOIN종류

INNER JOIN : JOIN ON 사용, NATURAL JOIN, USING JOIN 사용한다.

비교JOIN    EQ JOIN(EQUAL JOIN)

 

OUTER JOIN

 

SELF JOIN

 

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

이거뭐지???   찾아서 수정하기

SELECT employee_id, employees.department_id, department_name

FROM employees LEFT PULL OUTER JOIN departments

ON (employees.department_id = departments.department_id);

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

 

UNION : 결합,  여러 테이블의 행을 결합,

행수를 조절          ex) 매장직영점

 

집합 : UNION, UNION ALL(A합B), MINUS(교집합을뺀), INTERSECT(교집합)

UNION : 합집합  (여러테이블의 행을 결합)

MINUS : 차집합  

INTERSECT : 교집합

 

SELECT * FROM job_history

ORDER BY 

 

SELECT employee_id, first_name, job_id, department_id

FROM employees

빨간색 + 파란색 = 합집합

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

ㅡㅡ사원의 사번, 직무번호를 출력하시오.

SELECT employee_id, job_id

FROM employees;

 

ㅡㅡ사원의 경력정보(사번, 이전직무번호)를 출력하시오   --10건

SELECT employee_id, job_id

FROM job_history;

 

위 두개를 합치고 싶다!

ㅡㅡ이전경력정보와 현재사원의 사번, 직무번호를 출력하시오 

SELECT employee_id, job_id   ----115건
FROM employees
UNION
SELECT employee_id, job_id
FROM job_history
ORDER BY employee_id;

 

UNION ALL   --->   이전직무와 현재직무가 중복되어도 전부다 나오게한다

합집합

SELECT employee_id, job_id   ----117건FROM employees
UNION ALL
SELECT employee_id, job_id
FROM job_history
ORDER BY employee_id;

 

차집합

ㅡㅡ이전직무와 다른직무를 담당하는 사원의 사번, 직무번호를 출력하시오

SELECT employee_id, job_id   ----105건
FROM employees
MINUS

SELECT employee_id, job_id
FROM job_history
ORDER BY employee_id;

 

교집합

ㅡㅡ이전직무와 다른직무를 담당하는 사원의 사번, 직무번호를 출력하시오

SELECT employee_id, job_id   ----2건
FROM employees
INTERSECT

SELECT employee_id, job_id
FROM job_history
ORDER BY employee_id;