Join

유동현·2022년 11월 9일
0

오라클

목록 보기
12/18
post-thumbnail

Join

  • 2개 이상의 테이블을 합치는것

SQL 1992 CODE 버전

Cross Join

SELECT *
FROM EMP, DEPT;
--56건의 데이터 EMP 14건 DEPT 4건
--데카르트 곱하기(CATERSIAN PRODUCT)
-- 두 테이블을 결합한 모든 경우의 수

Equi Join

--EQUI JOIN : 서로 정확히 일치하는 것들끼리 연결하여 결합시키는 결합 방법
-- 두 테이블의 관계를 통해서 데이터를 완성해가는 구조
-- EQUI JOIN 이 JOIN 안에서 가장 많이 쓰인다.
SELECT *
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;
--14건의 결과

SELECT *
FROM EMP E, DEPT D   --이와 같이 명칭 붙이기 가능
WHERE E.DEPTNO = D.DEPTNO;

Equi Join 시 + 사용

--○ EQUI JOIN 시 (+) 를 활용한 결합 방법
SELECT *
FROM TBL_EMP;
--> 19명의 사원 있음
--  19명의 사원 중에 부서번호를 갖지 못한 사원들은 5명

SELECT *
FROM TBL_DEPT;
--> 5개의 부서 있음
--  5개의 부서 중 소속사원을 갖지 못한 부서는 2개 (40번, 50번 부서)


-- 서로 연결되는 것들끼리만 결합 한 거
SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO = D.DEPTNO;
--> 총 14건의 데이터가 결합되어 조회된 상황
--  즉, 부서번호를 갖지 못한 사원들(5명) 모두 누락
--  또한, 소속 사원을 갖지 못한 부서(2개) 모두 누락

-- 그런데, 이 때 
-- D.DEPTNO 뒤에 (+)를 사용하게 되면
SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO = D.DEPTNO(+);
--> 총 19건의 데이터가 결합되어 조회된 상황

-- E.DEPTNO 뒤에 (+)를 사용하게 되면
SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO;
--> 총 16건의 데이터가 결합되어 조회된 상황
--  D.DEPTNO 먼저 다 구성해놓고,
--  거기에 연결되는 E.DEPTNO 내용 가져오는 것!
--> 부서를 갖지못한 5명의 사원들 내용은 나오지 않음

-- (+) 얘로 인해서 처리되는 내용은
-- (+) 이게 없는 쪽의 데이터를 먼저 구성한 다음에
-- 거기에 맞는 아이들을 찾아서 추가하는 형식임
-- → 즉, (+)가 없는 쪽이 주인공, (+)가 붙어있는 애는 거기에 맞춰가는 애

-- 먼저 기본으로 (+) 없는 부분 한 다음에, 
-- 먼저 처리한 내용을 바탕으로 (+) 붙어있는 것과 맞는 거 있으면 
-- 추가 처리한다는 의미


--※ (+) 가 없는 쪽 테이블의 데이터를 모두 메모리에 먼저 적재한 후
--   (+) 가 있는 쪽 테이블의 데이터를 하나하나 확인하여 결합시키는 형태로
--   JOIN 이 이루어지게 된다.

--   이와 같은 이유로...
SELECT *
FROM TBL_EMP E, TBL_DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO(+);
--==>> 에러 발생
--     (ORA-01468: a predicate may reference only one outer-joined table)
-->>   이건 기준 없이 그냥 양쪽에서 첨가만 하겠다는 내용
--  즉 논리적으로 기준이 되는 테이블이 존재하지 않는다.
--   양쪽에 다 (+) 붙여놓은 위와 같은 쿼리문은 존재하지 않는다.
--   이런 형식의 JOIN 은 존재하지 않는다.

Non Equi Join

--○ NO EQUI JOIN : 범위 안에 적합한 것들끼리 연결하여 결합시키는 결합 방법
-- 정확하게 딱 일치하는 게 아니라, 어느 범위 안에 들어가 있는 것들 끼리 
-- SMITH 의 SAL : 800  → SALGRADE 1 (LOSAL 700 ~ HISAL 1200)
-- SALGRADE 안에 800에 정확하게 일치하는 레코드는 없다.
-- 그 범위 안에 들어가 있는 걸 찾는 거다.
SELECT *
FROM EMP;
SELECT *
FROM SALGRADE;

SELECT *
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;
-- 정확하게 일치하지 않지만, 
-- SALGRADE의 LOSAL~HISAL 의 범위 안에 들어가 있는 걸 찾음

SQL 1999 CODE

변경점

  • 1992 CODE의 EQUI JOIN 이 INNER JOIN 으로 바뀜
  • 『JOIN』 키워드 등장 → 『JOIN』(결합)의 유형 명시
  • 『ON』 키워드 등장 → 결합 조건은 WHERE 대신 『ON』으로

Inner Join

SELECT *
FROM EMP INNER JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;

SELECT *
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO;

-- 단 Inner 생략 가능

Outer Join

이전의 + 를 사용하던 Join을 대체한 방식으로 Outer역시 생략가능

SELECT *
FROM TBL_EMP E LEFT OUTER JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;   -- + 대신 기준이 왼쪽인 LEFT OUTER JOIN

SELECT *
FROM TBL_EMP E RIGHT OUTER JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO; -- + 대신 기준이 오른쪽인 RIGHT OUTER JOIN

SELECT *
FROM TBL_EMP E FULL OUTER JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO;   --누락됬던 부서와 사원들 모두 나오게 된다.

--OUTER 도 생략 가능하다. 즉 방향이 붙어있으면 OUTER 없으면 INNER JOIN이다.

---------------------------------------------------------------------
SELECT *
FROM TBL_EMP E JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO
AND E.JOB = 'CLERK'; --이러면 WHERE 대신 ON을 쓴 의미가 없다...


SELECT *
FROM TBL_EMP E JOIN TBL_DEPT D
ON E.DEPTNO = D.DEPTNO
WHERE E.JOB = 'CLERK';
--이처럼 쓰기를 권장하는데 이는 ON = 결합조건 WHERE = 선택조건
--으로 누가 봐도 한눈에 알 수 있게 만드는것
---------------------------------------------------------------------
-- PARSING 순서
-- FROM 에서 ON에 맞게 결합되게 만드는 거임
-- 그러므로 
-- WHERE 조건절보다 ON 이 먼저 처리된다.
-- FROM EMP 테이블과 DEPT 테이블
-- 거기에 ON에 맞게 처리!
-- 그리고 WHERE에 맞게 처리하게 됨

주의사항

  • 중복되는 칼럼 사용시 어떤 테이블의 칼럼인지 명시가 필요하다.
--○EMP 테이블과 DEPT 테이블을 대상으로
-- 직종이 MANAGER와 CLERK인 사원들만
-- 부서번호, 부서명, 사원명, 직종명, 급여 항목을 조회한다.

SELECT DEPT.DEPTNO "부서번호" , DEPT.DNAME "부서명", EMP.ENAME "사원명", EMP.JOB "직종명", EMP.SAL "급여"
FROM EMP LEFT JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO
WHERE JOB IN ('MANAGER','CLERK')
ORDER BY 4;
--에러 발생
--ORA-00918: column ambiguously defined
--두 테이블 간 중복되는 컬럼에 대한
-- 소속 테이블을 정해줘야(명시해줘야)한다.

--중복되는 컬럼값이 단 하나(ex, 20, 30, 40, 10)인 DEPTNO 가 부모테이블이되고
--각 데이터들에 DEPTNO의 값(20,30)이 여러개가 들어있는 EMP가 자식테이블이 된다.
--즉 이떄는 부모의 컬럼값 DEPT.DEPTNO로 값을 가져와야한다.




부모 테이블 구분법


--두 테이블에 모두 포함되어 있는 중복된 컬림이 아니더라도
--컬럼의 소속 테이블을 명시해 줄 수 있도록 권장한다. 오라클이 일을 덜하기 위해
--    즉, EMP 와 DEPT 중 둘 중 누가 부모냐에 따라서
--    EMP  가 부모 테이블이면, E.DEPTNO
--    DEPT 가 부모 테이블이면, D.DEPTNO
--    라고 해야 한다.

-- 어떤게 부모테이블인지, 자식테이블인지 어떻게 알아??
-- 두 테이블에 먼저 연결고리 컬럼이 있는지 확인하기
-- 둘 사이에 연결지을 컬럼 하나도 없다면 → 서로 관계없는 테이블
-- 연결고리 컬럼 있다면 → 부모-자식 성립할 수 있는 가능성 매우 높음!
--
-- 지금 여기서의
-- 연결고리 컬럼 → DEPTNO

-- 두 개의 테이블 조회 했을 때
SELECT *
FROM EMP;
SELECT *
FROM DEPT;
-- 연결고리 컬럼 DEPTNO를 봤을 때,
-- EMP  테이블에는 DEPTNO 값이 같은 컬럼이 여러개가 있음
-- DEPT 테이블에는 DEPTNO 값이 동일한 게 없음
-- 두 테이블 모두 DEPTNO 값 동일한게 여러개 있는 경우라면 → 신뢰성 깨짐
-- → 무결성 깨짐

-- DEPT에서는 DEPTNO 30번이 하나만 있어야 하지만,
-- EMP 에서는 DEPTNO 30번이 여러개가 있어도 되는 상황
-- → 『1:다』 상황

-- DEPT 테이블의 DEPTNO 30번을 
-- EMP  테이블에서 여러명의 사원이 참조하고 있는 상황

-- (부모 한 명에 여러명의 자식은 가능하니까)
-- DEPT 가 부모 테이블
-- EMP  가 자식 테이블


-- 왜 꼭 부모테이블을 참조하라고 했을까?
-- 하나는 E.DEPTNO를 하고, 하나는 D.DEPTNO를 참조하는데
-- OUTER JOIN 을 수행할 것이다.
-- 맨 마지막 15번째 줄에 둘이 차이가 있음
SELECT E.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO;
--==>>
/*
    :
(null)	OPERATIONS  (null)  (null)  (null)			    
*/
-- OPRATIONS 의 부서번호(DEPTNO) 가 보이지 않음

SELECT D.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO;
--==>>
/*
    :
    40	OPERATIONS  (null)  (null)  (null)			
*/
-- OPRATIONS 의 부서번호(DEPTNO) 가 보임

--> 이런 상황이면 부서번호(DEPTNO)가 보이게 조회해야 하는게 맞음
--  그러므로,
--  자식테이블을 참조하는 게 아니라, 부모테이블 것을 참조해야 한다.

-- 그러면, 나머지 컬럼 같은 경우에는 
-- 소속 테이블이 없더라도 문제가 생기지 않는다.
-- 그래도! 명시해주는 걸 당부한다.
SELECT D.DEPTNO, DNAME, ENAME, JOB, SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;

-- 위에처럼 작성하지 말고,
SELECT D.DEPTNO, D.DNAME, E.ENAME, E.JOB, E.SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;

-- 소속 테이블 명시하지 않으면
-- DNAME은 DEPT 테이블에 가서 ORACLE 에 가서 찾아옴
-- ENAME, JOB, SAL 은 EMP 테이블에 가서 ORACLE 이 찾아옴

-- ORACLE이 한 군데에 먼저 들어가서 찾는다면,
-- DEPTNO 에도 DEPT 테이블 명시하지 않아도 됐을 거다.
-- 왜냐면, ORACLE 이 DEPT TABLE이나 EMP TABLE 중 먼저 도착한 곳에서 가져오면 되니까

-- 그런데 DEPTNO라고 소속 테이블 명시하지 않았을 때, 에러가 생긴다는 것은
-- ORACLE이 DEPT TABLE과 EMP TABLE 둘 다 가본다는 것이다.

-- 소속 테이블이 명시되지 않으면
-- 해당 컬럼이 DEPT TABLE 에만 있다고 하더라도,
-- ORACLE은 DEPT TABLE, EMP TABLE 둘 다에 갔다 온다.
-- 그런데 우리가 정확하게 D.DNAME 으로 명시해놓는다면
-- ORACLE은 DEPT TABLE에만 갔다오면 된다.

--> ORACLE을 조금 더 배려하고, 조금 더 빠르게 실행하기 위해서!!

--※ 두 테이블에 모두 포함되어 있는 중복된 컬럼이 아니더라도
--   조인하는 과정에서 컬럼의 소속 테이블을 명시해줄 수 있도록 권장한다.


-- 최종적으로 쌤 문제 해결
SELECT D.DEPTNO, D.DNAME, E.ENAME, E.JOB, E.SAL
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
  AND E.JOB IN ('CLERK', 'MANAGER');

Using

  • 주로 DBA들이 사용하는 것이긴하나 알아두고는 있자
-- DBA들이 사용
SELECT DEPTNO, DNAME, ENAME, SAL
FROM EMP JOIN DEPT
USING(DEPTNO);
--> DEPTNO 를 사용해서 JOIN 해줘

Self Join

---------------------------------------------------------
-- 사원번호 사원명 직종명  관리자번호 관리자명 관리자직종명
---------------------------------------------------------
--   7369   SMITH  CLERK   7902      FORD     ANALYST
--    |       |      |       |        |          |
--   EMP1    EMP1   EMP1  EMP1(MGR)  EMP2       EMP2
--                           OR
--                        EMP2(EMPNO)

SELECT E1.EMPNO "사원번호", E1.ENAME "사원명", E1.JOB "직종명"
     , E2.EMPNO "관리자번호", E2.ENAME "관리자명", E2.JOB "관리자직종명"
FROM EMP E1 JOIN EMP E2
ON E1.MGR = E2.EMPNO;
--==>>
/*
7902	FORD	ANALYST	    7566	JONES	MANAGER
7788	SCOTT	ANALYST	    7566	JONES	MANAGER
7844	TURNER	SALESMAN	7698	BLAKE	MANAGER
7499	ALLEN	SALESMAN	7698	BLAKE	MANAGER
7521	WARD	SALESMAN	7698	BLAKE	MANAGER
7900	JAMES	CLERK	    7698	BLAKE	MANAGER
7654	MARTIN	SALESMAN	7698	BLAKE	MANAGER
7934	MILLER	CLERK	    7782	CLARK	MANAGER
7876	ADAMS	CLERK	    7788	SCOTT	ANALYST
7698	BLAKE	MANAGER	    7839	KING	PRESIDENT
7566	JONES	MANAGER	    7839	KING	PRESIDENT
7782	CLARK	MANAGER	    7839	KING	PRESIDENT
7369	SMITH	CLERK	    7902	FORD	ANALYST
*/
-- 여기서 끝이 아니다.
-- KING 이 누락되었음
-- KING 이 누락된 이유는?? 
-- KING 은 피라미드 정점에 있기 때문에, (JOB : PRESIDENT)
-- 회장님을 관리할 관리자가 없고,
-- 관리자 기반으로 묶은 SELF JOIN 에서 연결고리가 없기 때문에
-- 조회결과에서 누락됨,,,


-- 그러면
-- 1999 CODE 기반
SELECT E1.EMPNO "사원번호", E1.ENAME "사원명", E1.JOB "직종명"
     , E2.EMPNO "관리자번호", E2.ENAME "관리자명", E2.JOB "관리자직종명"
FROM EMP E1 LEFT JOIN EMP E2
ON E1.MGR = E2.EMPNO;
--==>>
/*
7902	FORD	ANALYST	    7566	JONES	MANAGER
7788	SCOTT	ANALYST	    7566	JONES	MANAGER
7900	JAMES	CLERK	    7698	BLAKE	MANAGER
7844	TURNER	SALESMAN	7698	BLAKE	MANAGER
7654	MARTIN	SALESMAN	7698	BLAKE	MANAGER
7521	WARD	SALESMAN	7698	BLAKE	MANAGER
7499	ALLEN	SALESMAN	7698	BLAKE	MANAGER
7934	MILLER	CLERK	    7782	CLARK	MANAGER
7876	ADAMS	CLERK	    7788	SCOTT	ANALYST
7782	CLARK	MANAGER	    7839	KING	PRESIDENT
7698	BLAKE	MANAGER	    7839	KING	PRESIDENT
7566	JONES	MANAGER	    7839	KING	PRESIDENT
7369	SMITH	CLERK	    7902	FORD	ANALYST
7839	KING	PRESIDENT  (null)  (null)	(null)	
*/
-- LEFT JOIN 해서,
-- 관리자번호 없지만 나오게 해줘야 한다!!


-- 위에 쿼리를 1992 CODE 기반으로 보자
SELECT E1.EMPNO "사원번호", E1.ENAME "사원명", E1.JOB "직종명"
     , E2.EMPNO "관리자번호", E2.ENAME "관리자명", E2.JOB "관리자직종명"
FROM EMP E1, EMP E2
WHERE E1.MGR = E2.EMPNO(+);
--==>>
/*
7902	FORD	ANALYST	    7566	JONES	MANAGER
7788	SCOTT	ANALYST	    7566	JONES	MANAGER
7900	JAMES	CLERK	    7698	BLAKE	MANAGER
7844	TURNER	SALESMAN	7698	BLAKE	MANAGER
7654	MARTIN	SALESMAN	7698	BLAKE	MANAGER
7521	WARD	SALESMAN	7698	BLAKE	MANAGER
7499	ALLEN	SALESMAN	7698	BLAKE	MANAGER
7934	MILLER	CLERK	    7782	CLARK	MANAGER
7876	ADAMS	CLERK	    7788	SCOTT	ANALYST
7782	CLARK	MANAGER	    7839	KING	PRESIDENT
7698	BLAKE	MANAGER	    7839	KING	PRESIDENT
7566	JONES	MANAGER	    7839	KING	PRESIDENT
7369	SMITH	CLERK	    7902	FORD	ANALYST
7839	KING	PRESIDENT  (null)  (null)	(null)	
*/

3개 이상의 Table을 Join

SQL 1992 CODE

--형식 1. (SQL 1992 CODE)

SELECT 테이블명1.컬럼명, 테이블명2.컬럼명, 테이블명3.컬럼명
FROM 테이블명1, 테이블명2, 테이블명3
WHERE 테이블명1.컬럼명1 = 테이블명2.컬럼명1
    AND 테이블명2.컬럼명2 = 테이블명3.컬럼명2;

SQL 1999 CODE

SELECT 테이블명1.컬럼명, 테이블명2.컬럼명, 테이블명3.컬럼명
FROM 테이블명1 JOIN 테이블명2 
ON 테이블명1.컬럼명1 = 테이블명2.컬럼명1
        JOIN 테이블명3
    ON 테이블명2.컬럼명2 = 테이블명3.컬럼명2;

사용 실습 1

--○ HR.JOBS, HR.EMPLOYEES, HR.DEPARTMENTS 테이블을 대상으로
--   직원들의 데이터를
--   FIRST_NAME, LAST_NAME, JOB_TITLE, DEPARTMENT_NAME 항목으로 조회한다.

SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

-- 일단 결과 누락된 거 없는지 확인해봄
SELECT COUNT(*)
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
--==>> 106

SELECT COUNT(*)
FROM EMPLOYEES;
--==>> 107
-- 하나 누락된 거 확인할 수 있음
-- Kimberely 누락됨. DEPARTMENT_ID 가 NULL 이라서
-- → OUTER JOIN 으로 묶어줘야 한다.

-- 결과 COUNT() 다르다고 해서, 무조건 크게 맞춰야 되는 건 아님
-- 업무에 따라서 정확하게 결합되어 있는 것만 봐야할 수도 있음
-- 서로 연결되지 않은거 안보이게 해야할 수도 있음
-- BUT,
-- 많은 경우에는 그렇지 않음
-- 이 경우에서도 부서번호가 누락되어 있는 사원 1명도 조회되게 해야한다.

-- LEFT JOIN 하면 결과 제대로 나오는지 확인해보기
SELECT COUNT(*)
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
--==>> 107


SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID;
      
        
-- 조회해봤으면 COUNT 해보기
SELECT COUNT(*)
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID;
--==>> 107

-- COUNT() 맞으니, 최종결과
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID;

사용 실습 2

--○ EMPLOYEES, DEPARTMENTS, JOBS, LOCAIONS, COUNTRIES, REGIONS 테이블을 대상으로
--   직원들의 데이터를 다음과 같이 조회할 수 있도록 쿼리문을 구성한다.
--   FIRST_NAME, LAST_NAME, JOB_TITLE, DEPARTMENT_NAME, CITY, COUNTRY_NAME, REGION_NAME
--   1992 CODE, 1999 CODE 두 가지로 풀어보기
--   최종 레코드 수는 107개여야 한다.

--① 문제 분석
SELECT *
FROM EMPLOYEES;
--> [FIRST_NAME, LAST_NAME], DEPARTMENT_ID(DEPARTMENTS), JOB_ID(JOBS)
SELECT *
FROM DEPARTMENTS;
--> [DEPARTMENT_NAME], LOCATION_ID(LOCATIONS), DEPARTMENT_ID
SELECT *
FROM JOBS;
--> [JOB_TITLE], JOB_ID
SELECT *
FROM LOCATIONS;
--> [CITY], COUNTRY_ID(COUNTRIES), LOCATION_ID
SELECT *
FROM COUNTRIES;
--> [COUNTRY_NAME], REGION_ID(REGIONS), COUNTRY_ID
SELECT *
FROM REGIONS;
--> [REGION_NAME], REGION_ID

-- [[1999 CODE]]
--①: 행 107개
SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

--②: 행 107개
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID;

--③-1: 행 106개 (DEPARTMENT_ID 가 NULL인 사원 있어서)
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
     , L.CITY
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID
        JOIN LOCATIONS L
        ON D.LOCATION_ID = L.LOCATION_ID;
        
--③-2: 행 107개 
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
     , L.CITY
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID
        LEFT JOIN LOCATIONS L
        ON D.LOCATION_ID = L.LOCATION_ID;
        

--④: 행 107개 (③번과 같은 이유로 LEFT JOIN 처리)
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
     , L.CITY, C.COUNTRY_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID
        LEFT JOIN LOCATIONS L
        ON D.LOCATION_ID = L.LOCATION_ID
        LEFT JOIN COUNTRIES C
        ON L.COUNTRY_ID = C.COUNTRY_ID;
        
--⑤(최종): 행 107개 [[1999 CODE]]
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
     , L.CITY, C.COUNTRY_NAME, R.REGION_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
        JOIN JOBS J
        ON E.JOB_ID = J.JOB_ID
            LEFT JOIN LOCATIONS L
            ON D.LOCATION_ID = L.LOCATION_ID
                LEFT JOIN COUNTRIES C
                ON L.COUNTRY_ID = C.COUNTRY_ID 
                    LEFT JOIN REGIONS R
                    ON C.REGION_ID = R.REGION_ID;
        
        
-- [[1992 CODE]] : 행 107개
SELECT E.FIRST_NAME, E.LAST_NAME, J.JOB_TITLE, D.DEPARTMENT_NAME
     , L.CITY, C.COUNTRY_NAME, R.REGION_NAME
FROM EMPLOYEES E, DEPARTMENTS D, JOBS J, LOCATIONS L, COUNTRIES C, REGIONS R 
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID(+)
  AND E.JOB_ID = J.JOB_ID
  AND D.LOCATION_ID = L.LOCATION_ID(+)
  AND L.COUNTRY_ID = C.COUNTRY_ID(+)
  AND C.REGION_ID = R.REGION_ID(+);

0개의 댓글