JOIN

JOIN 한 개 이상의 테이블에서 테이터를 조회하기 위해 사용하는 것으로, 수행 결과는 하나의 Result Set으로 나오게 됨
오라클 전용 구문 FROM절에 ','로 구분하여 합치게 될 TABLE명을 기술하고, WHERE절에 합치기에 사용할 컬럼명을 명시
SELECT
              EMP_ID
              , EMP_NAME
              , DEPT_CODE
              , DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID;

연결에 사용할 두 컬럼명이 다른 경우 그냥 사용
SELECT
              EMP_ID
              , EMP_NAME
              , EMPLOYEE.JOB_CODE
              , JOB_NAME
FROM EMPLOYEE, JOB
WHERE EMPLOYEE.JOB_CODE = JOB.JOB_CODE;

연결에 사용할 두 컬럼명이 같은 경우 테이블명, 컬럼명으로 작성해서 구분해서 사용
SELECT
              EMP_ID
              , EMP_NAME
              , E.JOB_CODE
              , JOB_NAME
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE = J.JOB_CODE;
ANSI 표준 구문 연결에 사용하려는 컬럼명이 같은 경우 USING()을 사용하고, 다른 경우 ON()을 사용 SELECT
              EMP_ID
              , EMP_NAME
              , JOB_CODE
              , JOB_NAME
FROM EMPLOYEE JOIN JOB USING(JOB_CODE);
연결에 사용하려는 컬럼명이 같은 경우 USING()을 사용하고, 다른 경우 ON()을 사용 SELECT
              EMP_ID
              , EMP_NAME
              , DEPT_CODE
              , DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

INNER JOIN 두 개 이상의 테이블을 조인할 때, 일치하는 값이 없는 행은 조인에서 제외 됨
이것을 INNER JOIN이라고 하며, 명시적으로 사용하지 않을 시에는 기본적으로 INNER JOIN 이다.
SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

OUTER JOIN 하지만 일치하지 않은 값 또한 JOIN에 포함시킬 수도 있다. 이것을 OUTER JOIN이라고 하며, 반드시 OUTER JOIN임을 명시해야 함.
1. LEFT OUTER JOIN 합치기에 사용한 두 테이블 중에 왼쪽 편에 기술된 테이블의 컬럼 수를 기준으로 JOIN을 할 때 사용
2. RIGHT OUTER JOIN 합치기에 사용한 두 테이블 중에 오른쪽 편에 기술된 테이블의 컬럼 수를 기준으로 JOIN을 할 때 사용
3. FULL OUTER JOIN 합치기에 사용한 두 테이블이 가진 모든 행을 결과에 포함 시킬 경우 사용
SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE
RIGHT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE
FULL JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
오라클 전용
SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE,DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID;
SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE,DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID(+);

** 에러발생, (+)는 한쪽에만 사용할 수 있다.

CROSS JOIN 카테이션곱(Cartensian projuct)
조인되는 테이블의 각 행들이 모두 매핑된 데이터가 검색되는 조인 방법으로, 검색되는 데이터 수는 행의 컬럼수 x 행의 컬럼수로 나오게 됨
  SELECT
              EMP_NAME
              , DEPT_TITLE
FROM EMPLOYEE
CROSS JOIN DEPARTMENT;
NON_EQU JOIN 지정한 컬럼 값이 일치하는 경우가 아닌, 값의 범위에 포함되는 행들을 연결하는 방식
  SELECT
              EMP_NAME
               , SALARY
              , E.SAL_LEVEL
              , S.SAL_LEVEL
FROM EMPLOYEE E
JOIN SAL_GRADE S ON (SALARY BETWEEN MIN_SAL AND MAX_SAL);
SELF JOIN 조인은 두 개 이상의 서로 다른 테이블을 연결하기도 하지만, 같은 테이블을 조인하는 경우도 있다. 이러한 경우 자기 자신과 조인을 맺는 것이라 하여 SELF JOIN
  SELECT
              E.EMP_ID
              , E.EMP_NAME 사원이름
              , E.DEPT_CODE
              , E.MANAGER_ID
              , M.EMP_NAME 관리자이름
FROM EMPLOYEE E , EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID;
다중 JOIN SELECT
              EMP_ID
              , EMP_NAME
              , DEPT_CODE
              , DEPT_TITLE
              , LOCAL_NAME
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN LOCATION ON (LOCATION_ID = LOCAL_CODE);

SUBQUERY

SUBQUERY 하나의 SELECT 문장의 절 안에 포함된 또 하나의 SELECT 문장이다.
서브쿼리는 메인쿼리가 실행되기 이전에 한번만 실행되며,
비교연산자의 오른쪽에 기술해야 하며, 반드시 괄호로 묶어야 한다.
또한 서브쿼리와 비교할 항목은 반드시 서브쿼리의 SELECT한 항목의 개수와 자료형을 일치시켜야 함
1. 단일행 서브쿼리 - 서브쿼리의 조회 결과 값의 개수가 1개 일 때
2. 다중행 서브쿼리 - 서브쿼리의 조회 결과 값의 행이 여러 개 일 때
3. 다중열 서브쿼리 - 서브쿼리의 조회 결과 컬럼의 개수가 여러 개 일 때  
4. 다중행 다중열 서브쿼리 - 서브쿼리의 조회 결과 컬럼의 개수와 행의 개수가 여러 개 일 때
5. 상(호연)관 서브쿼리 - 서브쿼리가 만든 결과값을 메인 쿼리가 비교 연산할 때, 메인 쿼리 테이블의 값이 변경되면 서브쿼리의 결과값도 바뀐다.
6. 스칼라 서브쿼리 - 상관쿼리 이면서 결과값이 한 개인 서브쿼리

전 직원의 평균 급여보다 많은 급여를 받고 있는 직원의 사번, 이름, 직급코드, 급여를 조회

SELECT
              EMP_ID
              , EMP_NAME
              , JOB_CODE
              , SALARY
FROM EMPLOYEE
WHERE SALARY >= (SELECT AVG(SALARY) FROM EMPLOYEE );

단일행(SINGLE ROW) 서브쿼리
전 직원의 급여 평균보다 급여를 많이 받는 직원의 이름, 직급, 부서, 급여 조회 SELECT
              EMP_NAME
              , JOB_CODE
              , DEPT_CODE
              , SALARY
FROM EMPLOYEE
WHERE SALARY >= (SELECT AVG(SALARY) FROM EMPLOYEE ) ORDER BY 2;

다중행(MULTIPLE ROW) 서브쿼리 1.다중행 서브쿼리 앞에는 일반 비교연산자 사용 불가
2.사용 가능 연산자 IN / NOT IN, >ANY / ALL / EXIST / NOT EXIST 등
부서별 최고 급여를 받는 직원의 이름, 직급 , 부서, 급여 조회 SELECT
              EMP_NAME
              , JOB_CODE
              , DEPT_CODE
              , SALARY
FROM EMPLOYEE
WHERE SALARY IN (SELECT MAX(SALARY)
FROM EMPLOYEE GROUP BY DEPT_CODE )
ORDER BY 3;

다중열 서브쿼리
- 퇴사한 여직원과 같은 부서, 같은 직급에 해당하는 사원의 이름, 직급, 부서, 입사일을 조회 SELECT
              EMP_NAME
              , JOB_CODE
              , DEPT_CODE
              , HIRE_DATE
FROM EMPLOYEE
WHERE (DEPT_CODE, JOB_CODE) IN (SELECT DEPT_CODE , JOB_CODE
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1) =2 AND ENT_YN = ‘Y’);

다중행 다중열 서브쿼리
직급별 최소 급여를 받는 직원의 사번, 이름, 직급, 급여 조회 SELECT
              EMP_ID
              , EMP_NAME
              , JOB_CODE
              , SALARY
FROM EMPLOYEE
WHERE (JOB_CODE, SALARY) IN (SELECT JOB_CODE , MIN(SALARY)
FROM EMPLOYEE GROUP BY JOB_CODE)

ORDER BY 3;

상(호연)관 서브쿼리
관리자가 있는 사원들 중 관리자의 사번이 EMPLOYEE테이블에 존재하는 직원의 사번, 이름, 소속부서, 관리자사번을 조회 SELECT
              EMP_ID
              , EMP_NAME
              , DEPT_CODE
              , MANAGER_ID
FROM EMPLOYEE E
WHERE EXISTS (SELECT EMP_ID
FROM EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID);

스칼라 서브쿼리 - SELECT절  
모든 사원의 사번, 이름, 관리자사번, 관리자명을 조회 SELECT
              E.EMP_ID
              , E.EMP_NAME
              , E.MANAGER_ID
              , NVL((SELECT M.EMP_NAME
FROM EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID),’없음’) AS 관리자명
FROM EMPLOYEE E
ORDER BY 1;

스칼라 서브쿼리 - WHERE절
자신이 속한 직급의 평균 급여보다 많이 받는 직원의 이름, 직급, 급여를 조회 SELECT
              EMP_NAME
              , JOB_CODE
              , SALARY
FROM EMPLOYEE E
WHERE SALARY >= (SELECT
                                          AVG(SALARY)
                                          FROM EMPLOYEE E2
                            WHERE E2.JOB_CODE = E.JOB_CODE) ORDER BY 2;
스칼라 서브쿼리 – ORDER BY절
모든 직원의 사번, 이름, 소속부서를 조회 후 부서명 내림차순으로 정렬 SELECT
            EMP_ID
              , EMP_NAME
              , DEPT_CODE
FROM EMPLOYEE
ORDER BY (SELECT
                            DEPT_TITLE
                            FROM DEPARTMENT
WHERE DEPT_CODE = DEPT_ID)
DESC NULLS LAST;
스칼라 서브쿼리 – ORDER BY절 SELECT
              DEPT_ID
              , DEPT_TITLE
FROM DEPARTMENT
ORDER BY DEPT_TITLE DESC;
FROM절에서의 서브쿼리(인라인뷰) FROM절에 서브쿼리를 사용한 것을 인라인뷰(INLINE-VIEW)라고 한다
* ROWNUM은 FROM절을 수행하면서 붙여지기 때문에 top-N분석 시 SELECT절에 사용한 ROWNUM이 의미 없게 됨 SELECT
              ROWNUM
              , EMP_NAME
              , SALARY
FROM EMPLOYEE
WHERE ROWNUM <= 5;
- FROM절에 이미 정렬이 수행된 서브쿼리(인라인뷰)를 적용 시, ROWNUM이 Top-N분석에 사용될 수 있음 SELECT
              ROWNUM
              , EMP_NAME
              , SALARY
FROM (SELECT
                            *
                            FROM EMPLOYEE
                            ORDER BY SALARY DESC
                            )
WHERE ROWNUM <= 5;
WITH 서브쿼리에 이름을 붙여 주고, 인라인뷰로 사용 시 서브쿼리의 이름으로 FROM절에 기술할 수 있다. 같은 서브쿼리가 여러 번 사용될 경우에 중복 작성을 피할 수 있고 실행 속도도 빨라진다는 장점
  WITH TOPN_SAL AS (SELECT
                                          EMP_ID
                                          , EMP_NAME
                                          , SALARY
                                          FROM EMPLOYEE
                                          ORDER BY SALARY DESC)
SELECT
              ROWNUM
              , EMP_NAME
              , SALARY
FROM TOPN_SAL;
RANK() OVER SELECT
              순위
              , EMP_NAME
              , SALARY
      FROM (SELECT
                            EMP_NAME
                            , SALARY
                            , RANK() OVER(ORDER BY SALARY DESC) AS 순위
FROM EMPLOYEE ORDER BY SALARY DESC);
DENSE_RANK() OVER SELECT
              순위
              , EMP_NAME
               , SALARY FROM (SELECT
                                          EMP_NAME
                                          , SALARY
                                         , DENSE_RANK() OVER(ORDER BY SALARY DESC) AS 순위
FROM EMPLOYEE
ORDER BY SALARY DESC);

 

SMALL

'SQL' 카테고리의 다른 글

SQL7 DML(Data Manipulation Language)  (0) 2023.01.17
SQL6 DDL(Data Definition Language)  (0) 2023.01.17
SQL3 GROUP BY & HAVING  (0) 2023.01.16
SQL2 FUNCTION  (0) 2023.01.13
SQL FUNCTION3  (0) 2023.01.12

+ Recent posts