**조인(JOIN)
->2개 이상의 테이블에서 찾고자하는 데이터를 검색하기 위해서
문제> 'King'의 부서이름을 출력하시오.
-> SELECT employee_id, department_id
FROM employees
WHERE last_name = 'King';
-> SELECT department_id, department_name
FROM departments
WHERE department_id IN(80, 90);
-> 이런 번거로움을 덜고자 조인을 이용
==>조인 이용
조인사용방법
-
내가 원하는 데이터가 무엇인가?(컬럼목록)
-
원하는 데이터가 어느 테이블에 있는가?
-
여러 테이블에 있다면 각각의 테이블의 공통컬럼을 찾는다.
->SELECT e.employee_id, e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND last_name = 'King';
퀴즈 kosta202> '송강' 교수가 강의하는 과목을 검색하라.
-> SELECT p.pno,p.pname,c.cname
FROM professor p, course c
WHERE p.pno= c.pno
AND pname = '송강';
<mission kosta202>
-
학점이 2학점인 과목과 이를 강의하는 교수를 검색하라.
-
화학과 1학년 학생의 기말고사 성적을 검색하라.
-
화학과 1학년 학생이 수강하는 과목을 검색하라.(3개 테이블 조인)
->SELECT c.cname, c.st_num, p.pname
FROM professor p, course c
WHERE p.pno = c.pno
AND st_num=2;
->SELECT s.syear,s.major, s.sname, c.result
FROM student s, score c
WHERE s.sno = c.sno
AND syear = 1 AND major = '화학';
->SELECT s.syear, s.major, s.sname,p.pname, c.cname
FROM student s, score s1, course c
WHERE s.cno = c1.cno
AND s1.cno = c.cno
AND syear = 1 AND major = '화학';
==> ANSI JOIN
(이전)
->SELECT e.employee_id, e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND last_name = 'King';
(이후)
->SELECT e.employee_id, e.department_id, d.department_name
FROM employees e INNER JOIN departments d
ON e.department_id = d.department_id
WHERE last_name = 'King'; //where절이 간단해서 쓰기 좋음.
-3개 이상 조인
->테이블1 JOIN 테이블2
ON 공통컬럼1 = 공통컬럼1
JOIN 테이블3
ON 공통컬럼2 = 공통컬럼2
퀴즈 hr>3개 이상 테이블을 조인하여 사원이름, 이메일, 부서번호, 부서이름, 직종번호(job_id), 직종이름(job_title)을 출력하라.
->SELECT e.last_name e.email, d.department_id, d.department_name, j.job_id, j.job_title
FROM employees e, departments d, jobs j
WHERE e.department_id = d.department_id
AND j.job_id = e.job_id;
->SELECT e.last_name e.email, d.department_id, d.department_name, j.job_id, j.job_title
FROM employees e INNER JOIN departments d
ON e.department_id = d.department_id
INNER JOIN jobs j
ON e.job_id = j.job_id;
퀴즈 hr> 'Seattle' (city)에 근무하는 사원이름, 부서번호, 직종번호, 직종이름, 도시이름을 출력하라
->SELECT e.last_name, e.department_id, j.job_id, j.job_title, l.city
FROM employees e INNER JOIN jobs j
ON e.job_id = j.job_id
INNER JOIN departments d
ON e.department_id = d.department_id
INNER JOIN locations l
ON l.location_id = d.location_id
WHERE l.city = 'Seattle';
** SELF 조인
=> 'Kochhar' 직속상사의 정보를 출력하라.
->SELECT A.last_name || '의 매니저는 ' || B.last_name || '이다.'
FROM employees A, employees B
WHERE A.manager_id = B.employee_id //a의 매니저이름을 b의 직원이름으로 가져옴
AND A.last_name = 'Kochhar';
퀴즈 kosta202> 학생 중에 동명이인을 검색하라.
->SELECT a.sno, a.sname,b.sno, b.sname
FROM student a, student b
WHERE a.sname = b.sname AND a.sno != b.sno;
->SELECT DISTINCT a.sno, a.sname //중복제거
FROM student a, student b
WHERE a.sname = b.sname AND a.sno != b.sno;
★★면접 **INNER JOIN VS OUTER JOIN, index, 주식별자/비식별자, dom
inner join : 공통된 부분 조인
outer join : 공통되지 않은 부분까지 조인
**OUTER조인(외부 조인)
SELECT * FROM employees; 107row
->SELECT e.employee_id, e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(106row)
데이터값이 없더라도 누락된 값없이 조회되기를 원함. => 아웃조인
->OUTER JOIN 적용
->SELECT e.employee_id, e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(+); //e에 있는 department_id가 null이면 그 반대식에 +를 적용
**ANSI JOIN(outer join)
->SELECT e.employee_id, e.department_id, d.department_name
FROM employees e LEFT JOIN departments d (null이 발생하는 값(데이터가 없는쪽)에 LEFT/LIGHT써줌)
ON e.department_id = d.department_id;
퀴즈 kosta202 > 이번 학기 등록된 과목에 대한 모든 교수를 검색하라. (등록하지 않아도 교수 출력)
SELECT * FROM professor; (36rows)
SELECT * FROM course; (32rows)
Inner Join(29rows)
SELECT p.pno, p.pname, p.section, c.cname
FROM professor p JOIN course c
ON p.pno = c.pno; (32rows)
Outer Join(32rows)
SELECT c.pno, c.cname, c.st_num, p.pname
FROM professor p ,course c
ON p.pno = c.pno(+);
SELECT c.pno, c.cname, c.st_num, p.pname
FROM professor p LEFT JOIN course c
ON p.pno = c.pno;
SELECT c.pno, c.cname, c.st_num, p.pname
FROM professor p FULL JOIN course c
ON p.pno = c.pno; (양쪽 누락값 다 추출)
**조인 퀴즈(내가푼것)
--1 이름이 ‘Himuro’인 사원의 부서명을 출력하라.
SELECT d.department_name
FROM employees e ,departments d
WHERE e.department_id = d.DEPARTMENT_ID
AND last_name = 'Himuro';
--2 직종명이 'Accountant'인 사원의 이름과 부서명을 출력하라.
SELECT e.last_name, d.department_name
FROM employees e INNER JOIN jobs j
ON e.job_id = j.job_id
INNER JOIN departments d
ON d.department_id = e.department_id
WHERE job_title = 'Accountant';
--3 커미션을 받는 사람의 이름과 그가 속한 부서를 출력하라.
SELECT e.last_name, department_name
FROM employees e, departments d
WHERE e.department_id = d.DEPARTMENT_ID
AND e.commission_pct IS NOT NULL;
--4 급여가 4000이하인 사원의 이름, 급여, 근무지를 출력하라.
SELECT e.last_name, e.salary, l.city
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id AND d.location_id=l.location_id
AND e.salary <=4000;
--5 'Chen'과 동일한 부서에서 근무하는 사원의 이름을 출력하라.
SELECT e2.last_name
FROM employees e, employees e2
WHERE e.department_id = e2.department_id
AND e.last_name = 'Chen';
**조인 답 (강사님 코드)
1. 이름이 ‘Himuro’인 사원의 부서명을 출력하라.
SELECT*FROM employees;
SELECT*FROM departments;
SELECT em.last_name, de.department_name
FROM employees em, departments de
WHERE em.department_id = de.department_id
AND em.last_name = 'Himuro';
SELECT em.last_name, de.department_name
FROM employees em
JOIN departments de
ON em.department_id = de.department_id
WHERE em.last_name = 'Himuro';
2. 직종명이 'Accountant'인 사원의 이름과 부서명을 출력하라.
SELECT*FROM employees;
SELECT*FROM jobs;
SELECT*FROM departments;
SELECT jobs_title, last_name, demaprtment_name
FROM jobs js, emlpoyees es, departments ds
WEHRE js.job_id = es.job_id
AND es.department_id = ds.department_id;
SELECT js.job_title, es.last_name, ds.department_name
FROM jobs js
JOIN emlpoyees es
ON js.job_id = es.job_id
JOIN departments ds
ON es.department_id = ds.department_id;
3. 커미션을 받는 사람의 이름과 그가 속한 부서를 출력하라.
SELECT*FROM employees;
SELECT*FROM departments;
SELECT es.commission_pct, ds.department_name, es.last_name
FROM employees es, departments ds
WEHRE es.department_id = ds.department_id;
SELECT es.commission_pct, ds.department_name, es.last_name
FROM employees es
JOIN departments ds
ON es.department_id = ds.department_id;
4. 급여가 4000이하인 사원의 이름, 급여, 근무지를 출력하라.
SELECT*FROM employees
SELECT*FROM departments
SELECT*FROM locations ls
SELECT es.last_name, es.salary, ls.city
FROM employees es, departments ds, locations ls
WHERE es.department_id = ds.department_id
AND ds.location_id = ls.location_id
AND es.salary<4000;
SELECT es.last_name, es.salary, ls.city
FROM employees es
JOIN departments ds
ON es.department_id = ds.department_id
JOIN locations ls
ON ds.location_id = ls.location_id
WHERE es.salary<4000;
5. 'Chen'과 동일한 부서에서 근무하는 사원의 이름을 출력하라.
SELECT*FROM employees;
SELECT A.last_name, B.last_name
FROM employees A, employees B
WHERE A.department_id = B.department_id
AND A.last_name = 'Chen';
SELECT A.last_name, B.last_name
FROM employees A
JOIN employees B
ON A.department_id = B.department_id
WHERE A.last_name = 'Chen';
SELECT A.last_name, B.last_name
FROM employees A
JOIN employees B
ON A.department_id = B.department_id
WHERE A.last_name = 'Chen';
SELECT A.last_name, B.last_name
FROM employees A, employees B
WHERE A.department_id = B.department_id
AND A.last_name = 'Chen';
모든~~ =OUTER JOIN!!
SQL#4 퀴즈
--1
SELECT * FROM EMP;
SELECT * FROM DEPT;
SELECT * FROM BONUS;
SELECT * FROM SALGRADE;
SELECT d.deptno, d.dname, e.empno, e.ename, e.sal
FROM dept d, emp e
WHERE d.deptno = e.deptno
AND SAL >2000;
--2
SELECT d.deptno, d.dname, TRUNC (avg(sal),0) AS AVG_sAL, max(sal) AS MAX_SAL, min(sal) AS MIN_SAL, count(*) AS CNT
FROM dept d, emp e
WHERE d.deptno = e.deptno
GROUP BY d.deptno, d.dname;
--3
SELECT d.deptno, d.dname, e.empno, e.ename,e.job,e.sal
FROM dept d LEFT JOIN emp e
ON d.deptno = e.deptno
ORDER BY d.DEPTNO, e.ename;
--4 self join & outer join
SELECT DISTINCT d.deptno, d.dname,
e.empno, e.ename,e.mgr, e.sal, e.deptno AS DEPTNO_1,
s.losal, s.hisal, s.grade,
e2.empno AS MGR_EMPNO, e2.ename AS MGR_ENAME
--FROM dept d , emp e, salgrade s, emp e2
-- WHERE d.deptno = e.deptno(+)
--AND e.sal BETWEEN s.losal(+) AND s.hisal(+)
--AND e.mgr = e2.empno(+)
--ORDER BY d.deptno, e.empno;
FROM emp e LEFT JOIN emp e2 --매니저가 없을 수도 있으니까 왼쪽이 더 큼
ON e.mgr = e2.empno
LEFT JOIN salgrade s //s보다 원래 있던 값들이 데이터범위 더 큼
ON e.sal BETWEEN s.losal AND s.hisal
RIGHT JOIN dept d
ON e.deptno = d.deptno
ORDER BY d.deptno, e.empno;
-- 강사님코드
-- 8-1
-- SQL-99 �씠�쟾 諛⑹떇
SELECT D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME, E.SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.SAL > 2000;
-- SQL-99諛⑹떇
SELECT DEPTNO, D.DNAME, E.EMPNO, E.ENAME, E.SAL
FROM EMP E NATURAL JOIN DEPT D //공통부분 조인
WHERE E.SAL > 2000;
-- 8-2
--SQL-99 �씠�쟾 諛⑹떇
SELECT D.DEPTNO,
D.DNAME,
TRUNC(AVG(SAL)) AS AVG_SAL,
MAX(SAL) AS MAX_SAL,
MIN(SAL) AS MIN_SAL,
COUNT(*) AS CNT
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
GROUP BY D.DEPTNO, D.DNAME;
--SQL-99 諛⑹떇
SELECT DEPTNO,
D.DNAME,
TRUNC(AVG(SAL)) AS AVG_SAL,
MAX(SAL) AS MAX_SAL,
MIN(SAL) AS MIN_SAL,
COUNT(*) AS CNT
FROM EMP E JOIN DEPT D USING (DEPTNO) //using = on
GROUP BY DEPTNO, D.DNAME;
-- 8-3
--SQL-99 �씠�쟾 諛⑹떇
SELECT D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME, E.JOB, E.SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO
ORDER BY D.DEPTNO, E.ENAME;
--SQL-99 諛⑹떇
SELECT D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME, E.JOB, E.SAL
FROM EMP E RIGHT OUTER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
ORDER BY D.DEPTNO, E.ENAME;
-- 8-4
--SQL-99 �씠�쟾 諛⑹떇
SELECT D.DEPTNO, D.DNAME,
E.EMPNO, E.ENAME, E.MGR, E.SAL, E.DEPTNO,
S.LOSAL, S.HISAL, S.GRADE,
E2.EMPNO AS MGR_EMPNO, E2.ENAME AS MGR_ENAME
FROM EMP E, DEPT D, SALGRADE S, EMP E2
WHERE E.DEPTNO(+) = D.DEPTNO
AND E.SAL BETWEEN S.LOSAL(+) AND S.HISAL(+) // between값에 포함안되어도 null값으로 추출해라.
AND E.MGR = E2.EMPNO(+)
ORDER BY D.DEPTNO, E.EMPNO;
--SQL-99諛⑹떇
SELECT D.DEPTNO, D.DNAME,
E.EMPNO, E.ENAME, E.MGR, E.SAL, E.DEPTNO,
S.LOSAL, S.HISAL, S.GRADE,
E2.EMPNO AS MGR_EMPNO, E2.ENAME AS MGR_ENAME
FROM EMP E RIGHT OUTER JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO)
LEFT OUTER JOIN SALGRADE S
ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)
LEFT OUTER JOIN EMP E2
ON (E.MGR = E2.EMPNO)
ORDER BY D.DEPTNO, E.EMPNO;
**SQL3 과제
--sql 3
SELECT * FROM EMP;
--1
SELECT deptno, TRUNC(avg(sal),0) AS AVG_SAL,
max(sal) AS MAX_SAL, min(sal) AS MIN_SAL, COUNT(*) AS CNT
FROM emp
GROUP BY deptno
ORDER BY deptno DESC;
--2
SELECT job, count(*)
FROM EMP
GROUP BY job
HAVING COUNT(*)>=3;
--3
SELECT DISTINCT TO_CHAR(HIREDATE,'YYYY') AS HIRE_YEAR, DEPTNO, COUNT(*) AS CNT
FROM EMP
GROUP BY TO_CHAR(HIREDATE,'YYYY'), DEPTNO;
--4
SELECT * FROM EMP;
SELECT NVL2(COMM,'O','X') AS EXIST_COMM, COUNT(*) AS CNT
FROM EMP
GROUP BY NVL2(COMM,'O','X');
--5
SELECT DEPTNO, TO_CHAR(HIREDATE,'YYYY') AS HIRE_YEAR , COUNT(*) AS CNT,
max(sal) AS MAX_SAL, sum(sal) AS SUM_SAL, avg(sal) AS AVG_SAL
FROM EMP
GROUP BY ROLLUP(DEPTNO, TO_CHAR(HIREDATE,'YYYY')); -> 3가지의 총합계가 보임
1. 부서별, 2. 날짜별, 3. 총합
★★모든 데이터를 조인해라 => 아우터 조인
'FULLSTACK > DB' 카테고리의 다른 글
DB 6차시 - 제어문(조건문), 예외처리, 커서, 프로시저, 함수 (0) | 2020.11.13 |
---|---|
DB 5차시 - 인덱스, 뷰, 시퀀스, PL/SQL (0) | 2020.11.13 |
DB 4차시 - 서브쿼리문 (0) | 2020.11.13 |
DB 2차시 - 그룹함수, 다양한 함수들, DDL, DML (0) | 2020.11.13 |
DB 1차시 - DB개념, 연산자 (0) | 2020.11.13 |