[230706] SELECT문 실행순서/조인 (DAY 7) - 구디아카데미후기 IT국비지원 민경태 강사님

MJ·2023년 7월 7일

수업 TIL🐣💚

목록 보기
7/68

🔸SELECT문 실행순서

SELECT 칼럼 - 5
  FROM 테이블 - 1
 WHERE 조건 - 2
 GROUP BY 그룹 - 3
HAVING 그룹조건 - 4
 ORDER BY 정렬 - 6
-- 사원 테이블에서 부서별 연봉 평균과 사원수를 조회하시오. 부서별 사원수가 2명 이상인 부서만 조회하시오.
/* 불가능 */
SELECT DEPARTMENT_ID         AS 부서번호
     , ROUND(AVG(SALARY), 2) AS 평균연봉
     , COUNT(*)              AS 사원수    -- 4
  FROM EMPLOYEES                          -- 1
 GROUP BY DEPARTMENT_ID                   -- 2
HAVING 사원수 >= 2                        -- 3 
--HAVING 절이 실행되는 순서에서는 별명 '사원수'가 존재하지 않기 때문에 오류 발생
 ORDER BY DEPARTMENT_ID;                  -- 5
/* 가능 */
SELECT DEPARTMENT_ID         AS 부서번호
     , ROUND(AVG(SALARY), 2) AS 평균연봉
     , COUNT(*)              AS 사원수    -- 4
  FROM EMPLOYEES                          -- 1
 GROUP BY DEPARTMENT_ID                   -- 2
HAVING COUNT(*) >= 2                      -- 3
 ORDER BY 부서번호;                       -- 5 
 --ORDER BY 절이 실행되기 직전인 SELECT 절에서 "부서번호" 별명이 지정되었기 때문에 사용 가능

조인

  1. 2개 이상의 테이블을 한 번에 조회하는 방식
  2. 각 테이블의 관계(1:M)를 이용해서 조인 조건을 만듦
  3. 조인 종류
    1) 내부 조인 : 2개 테이블 양쪽에 모두 존재하는 데이터만 조회하는 방식
    2) 외부 조인 : 2개 테이블 양쪽에 모두 존재하지 않더라도 조회하는 방식
    3) 크로스 조인 - 엄청 맣은 결과 나오고 속도도 느림
    4) 셀프 조인

🔻드라이브 테이블과 드리븐 테이블

  1. 드라이브 테이블
    1) 조인 관계를 처리하는 메인 테이블
    2) 1:M 관계에서 1에 해당하는 테이블
    3) 일반적으로 데이터의 갯수가 적음
    4) PK를 조인 조건으로 사용하기 때문에 인덱스(INDEX) 사용이 가능 (빠르다는 의미)
  2. 드리븐 테이블
    1) 1:M 관계에서 M에 해당하는 테이블
    2) 일반적으로 데이터의 갯수가 많음
    3) FK를 조인 조건으로 사용하기 때문에 인덱스(INDEX) 사용이 불가능 (느리다는 의미)
  3. 드라이브 테이블을 드리븐 테이블보다 먼저 작성하면 성능에 도움됨

🔻ANSI 조인

: 표준 구문 작성법

SELECT 테이블1.칼럼, 테이블2.칼럼, ...
FROM 테이블1 JOIN 테이블2
ON 조인_조건

내부조인

--사원번호, 사원명, 부서번호, 부서명 조회
--사원번호, 사원명, 부서번호 = EMPLOYEES
--부서번호, 부서명 = DEPARTMENTS
SELECT EMPLOYEE_ID
     , FIRST_NAME
     , LAST_NAME
     , D.DEPARTMENT_ID  
-- 2개의 테이블에 모두 있는 칼럼(이름이 같은 칼럼)은 반드시 테이블(오너)을 명시. 
-- 알아볼 수 있는 것도 오너 명시하면 좋음
     , DEPARTMENT_NAME
  FROM DEPARTMENTS D INNER JOIN EMPLOYEES E
    ON D.DEPARTMENT_ID = E.DEPARTMENT_ID;

외부조인

  • LEFT OUTER JOIN : 왼쪽에 있는 테이블은 일치하는 값이 오른쪽 테이블에 없더라도 조인 결과에 모든 값 포함, 오른쪽 테이블은 일치하는 값만 포함 (RIGHT OUTER JOIN은 반대)
/*모든 사원들의(부서가 없는 사원도 포함) 사원번호, 사원명, 부서번호, 부서명을 조회하시오.*/
SELECT EMPLOYEE_ID
     , FIRST_NAME
     , LAST_NAME
     , D.DEPARTMENT_ID
     , DEPARTMENT_NAME
  FROM DEPARTMENTS D RIGHT OUTER JOIN EMPLOYEES E  
  -- 오른쪽 테이블(EMPLOYEES)의 모든 데이터 조회. (부서번호가 없는 사원도 조회.)
    ON D.DEPARTMENT_ID = E.DEPARTMENT_ID;
/*사원번호, 사원명, 부서번호, 부서명을 조회하시오. 사원이 근무하지 않는 유령 부서도 조회하시오.*/
SELECT EMPLOYEE_ID
     , FIRST_NAME
     , LAST_NAME
     , D.DEPARTMENT_ID
     , DEPARTMENT_NAME
  FROM DEPARTMENTS D LEFT OUTER JOIN EMPLOYEES E  
  -- 왼쪽 테이블(DEPARTMENTS)의 모든 데이터를 조회 (사원이 근무하지 않는 부서도 조회)
    ON D.DEPARTMENT_ID = E.DEPARTMENT_ID;

FROM절 적는 법

-- 모든 사원들의 EMPLOYEE_ID, FIRST_NAME, DEPARTMENT_NAME을 조회하시오. 부서가 없는 사원의 부서명은 'None'으로 조회되도록 처리하시오.
SELECT E.EMPLOYEE_ID, E.FIRST_NAME, NVL(D.DEPARTMENT_NAME, 'None')
  FROM DEPARTMENTS D RIGHT OUTER JOIN EMPLOYEES E
    ON D.DEPARTMENT_ID = E.DEPARTMENT_ID
 ORDER BY E.EMPLOYEE_ID;
  1. 1:M에서 1인 DEPARTMENTS를 M인 EMPLOYEES보다 먼저 적음 (성능 향상)
    • 참조하는 화살표 방향 생각해보기 (참조되는 게 1, 참조하는 게M측이니까)
  2. 모든 정보를 구해야하는 쪽이 드라이브 테이블이고 그 방향으로 JOIN
    • 모든 사원을 구하는 거니까 EMPLOYEES가 드라이브 테이블 -> RIGHT OUTER JOIN

3개 이상 테이블 조인

-- 부서번호, 부서명, 근무도시, 근무국가를 조회하시오.
-- 사원번호, 사원명, 부서번호 - EMPLOYEES
-- 부서번호, 부서명, 근무지역 - DEPARTMENT
-- 근무지역 - LOCATION
SELECT DEPARTMENT_ID
     , DEPARTMENT_NAME
     , CITY
     , COUNTRY_NAME
  FROM COUNTRIES C INNER JOIN LOCATIONS L
    ON C.COUNTRY_ID = L.COUNTRY_ID INNER JOIN DEPARTMENTS D
    ON L.LOCATION_ID = D.LOCATION_ID;
    --LOCATIONS L INNER JOIN DEPARTMENTS D
    --ON L.LOCATION_ID = D.LOCATION_ID 이 1차 조인 결과 전체를 테이블 하나로 보는 것

🔻오라클 조인

/*내부 조인
사원번호, 사원명, 부서번호, 부서명 조회*/
-- 사원번호, 사원명, 부서번호 - EMPLOYEES
-- 부서번호, 부서명 - DEPARTMENTS
SELECT EMPLOYEE_ID
     , FIRST_NAME
     , LAST_NAME
     , D.DEPARTMENT_ID 
     , DEPARTMENT_NAME
  FROM DEPARTMENTS D, EMPLOYEES E -- INNER JOIN 대신 콤마 사용
 WHERE D.DEPARTMENT_ID = E.DEPARTMENT_ID; -- ON 대신 WHERE 사용
/*외부 조인
모든 사원들의(부서가 없는 사원도 포함) 사원번호, 사원명, 부서번호, 부서명 조회*/
SELECT EMPLOYEE_ID
     , FIRST_NAME
     , LAST_NAME
     , D.DEPARTMENT_ID
     , DEPARTMENT_NAME
  FROM DEPARTMENTS D, EMPLOYEES E 
  -- 오른쪽 테이블(EMPLOYEES)의 모든 데이터 조회 (EMPLOYEES에서 부서번호가 없는 사원도 조회)
 WHERE D.DEPARTMENT_ID(+) = E.DEPARTMENT_ID; -- RIGHT OUTER JOIN은 반대방향(LEFT)에 '+' 추가함
/*사원번호, 사원명, 부서번호, 부서명 조회. 사원이 근무하지 않는 유령 부서도 조회*/
SELECT EMPLOYEE_ID
     , FIRST_NAME
     , LAST_NAME
     , D.DEPARTMENT_ID
     , DEPARTMENT_NAME
  FROM DEPARTMENTS D, EMPLOYEES E 
  -- 왼쪽 테이블(DEPARTMENTS)의 모든 데이터 조회 (사원이 근무하지 않는 부서도 조회)
 WHERE D.DEPARTMENT_ID = E.DEPARTMENT_ID(+); --LEFT OUT JOIN은 반대방향(RIGHT)에 '+' 추가함
 /*3개 이상 테이블 조인*/
-- 사원번호, 사원명, 부서번호, 부서명, 지역번호, 지역명(도시)을 조회
-- 사원번호, 사원명, 부서번호 - EMPLOYEES
-- 부서번호, 부서명, 근무지역 - DEPARTMENT
-- 근무지역 - LOCATION
SELECT E.EMPLOYEE_ID
     , E.FIRST_NAME
     , E.LAST_NAME
     , D.DEPARTMENT_ID
     , D.DEPARTMENT_NAME
     , L.LOCATION_ID
     , L.CITY
  FROM LOCATIONS L, DEPARTMENTS D, EMPLOYEES E
 WHERE L.LOCATION_ID = D.LOCATION_ID
   AND D.DEPARTMENT_ID = E.DEPARTMENT_ID; 


🟢 구디아카데미후기 IT국비지원 민경태 강사님 수업 7일차! 🟢
슬슬 어려워지는 느낌 조인은 열심히 연습해야겠다 😅 연습문제 받은 것들 풀면서 벨로그 쓴 것도 다시 읽어봐야지 ☆*: .。.

0개의 댓글