5월 21일 금요일 (9일차) - 등가조인,포괄조인ㅇ

@_@·2021년 5월 21일
0

Database

목록 보기
16/28

<목차>
ㅇ 등가 조인
ㅇ 포괄 조인


ㅇ 참고자료 <Do it! 오라클로 배우는 데이터베이스 입문>


(내생각) 윗도리랑 바지 이야기로 이해하면 쉬운 듯




ㅇ 조인조건의 종류

(2개 이상의 테이블에 수행)

  • 등가 조인 : 조인시킬 테이블에 같은 데이터가 존재할 때
    • = 연산자 사용
    • 현업에서 발생하는 99%가 이거야. 또한 얘의 99%가 PK=FK 야ㅋㅋㅋ
  • 비등가 조인 : 데이터가 다를 때
    • 다른 비교연산자 사용. 가장 많이 사용하는 건 비트윈
  • 포괄 조인 : 어느 한쪽 테이블에 데이터가 더 많을 때
    • 적은 쪽에 (+)를 붙여

CF. 실제로는 이 3개가 조인조건의 종류야 (데이터가 같게/다르게/한쪽이많게)

(1개의 테이블에 수행)

  • 자체 조인
    • 조인시킬 테이블이 한 개야
    • 셀프조인 내에서 이큐.논이큐.아우터 조인
    • 가장 어렵고 이해하기도 힘들어



ㅇ 등가조인 이큐조인 equi join

  • 테이블에 같은 데이터 존재할 시 수행
  • PRIMARY KEY와 FOREIGN KEY로 연결되어 있는 테이블에서 가장 많이 발생
    • 참조하고 있기 때문에 데이터 값이 틀릴래야 틀릴 수 없어ㅋㅋ
  • 물론 꼭 PK,FK일 필요는 없긴 해. 데이터 타입만 같으면 돼 (연산자 = 를 쓰기 때문에)
    • salary 20000 과 부서번호 10번 등가조인 실행은 되지만 no row selected. 뜨겠지.
      (있더라도 의미 없는 실행이 되겠지)
  • 즉, 조인조건은 PK=FK 이렇게 두는 게 99.999%
  • 현업에서는 딱 이것만 알려주면 끝나

ㅇ 실습

SELECT e.last_name, d.department_name, e.department_id
FROM employees e, departments d
WHERE e.department_id=d.department_id

106 rows selected.

  • 사원 107명인데 어디 갔어?? 왜 106명 나와?
    • 부서 번호가 없는 애가 있어서
  • 예를 들어 사원테이블에서는 150번 사원이 d_id가 NULL일 수 있지만
    부서테이블에서는 d_id가 PK라서 NULL을 가질 수 없어
    즉, e.d_id = d.d_id 라는 식이 성립하지 않아.

CF. (내생각)
e에서는 e_id가 PK이고 d_id는 FK
d_id가 FK라는 말은 d의 d_id를 참조 정도 하겠다는 거지 무조건 사용한다는 말은 아냐.
즉, 어떤 행은 d_id 없을 수도 있어. 이런 행은 세어지지 않아.
Q. 그러면 항상 FK=PK(+) 이렇게 사용해줘야 하는 거 아닐까??
PK를 사용하지 않는 애들은 NULL 처리 돼서 언급되도록?!
A. 문제 상황에서 요구하는 게 뭔지에 따라 잘 써줘야 할 듯
-> 포괄조인 필요하다면 '모든 사원' 이런 식으로 언급해줘
-> 사원이 없더라도 '모든 부서'를 보고 싶다면 (+)FK=PK 되겠지~


ㅇ AND 연산자 사용한 추가 검색 조건

ㅇ실습 : 90번 부서에 근무하는 사원 이름, 급여, 근무하는 부서이름을 출력하자.

  • 풀이 순서 (지금까지와 똑같이 하면 돼~~)
    • 셀렉트 리스트 결정하기 : 이름, 급여, 부서
    • 프럼절 : 테이블이 2개 필요하네? => 조인
      • 알리아스 쓰고 셀렉트에 접두어 붙여
    • 조인조건 : 2-1=1개, PK=FK
    • 추가 조건 : 90번 부서
      • 사원에 대해 얘기하고 있고, d에는 사원이 없는 부서번호도 존재하므로 e에서 찾자
      • 조건이 추가되니까. AND로 조건절 추가
  • 일반 조건은 '그리고' 만족해야 하는 조건이므로 AND
    • OR로 묶으면 카테시안 곱이 실행돼버려
  • 순서는 상관없어. WHERE 일반 조건 AND 조인조건 가능
    • 다만, 성능상으로는 조인을 먼저
    • 합쳐 놓고 필터링하는 게 먼저 필터링 후 합치는 것보다 낫잖아
      (버리고 나서 정리하는 것보다 정리하고 나서 버리는 게 낫지)

ㅇ 세 개 이상의 테이블 조인

  • 조인 조건 : e.d_id=d.d_id, d.lo=l.lo
  • 사원들 이름과 각자가 근무하는 부서 이름과 도시를 알고 싶을 때
SELECT e.last_name, d.department_name, l.city
FROM employees e, departments d, locations l
WHERE e.department_id=d.department_id 
AND d.location_id=l.location_id
  • Q. l.city의 l은 1인가요?
    A. 알리아스는 숫자로 시작할 수 없어

  • 내실험) 사원들 이름과 근무하는 도시를 알고 싶을 때
    (즉 d 테이블에는 셀렉트절이 없어, 하지만 조인하려면 필요해)

SELECT e.last_name, l.city
FROM employees e, departments d, locations l
WHERE e.department_id=d.department_id 
AND d.location_id=l.location_id

이렇게 하면 답 잘 나와

만약 셀렉트 절에 없으니까 FROM에서 d테이블 빼버린다면? 에러나
내가 이미 조인조건에서 d.department_id 라고 d테이블의 접두어를 사용했어
이거 풀네임으로 써도 결국 프롬절에 안 쓰면 에러나

SELECT e.last_name, l.city
FROM employees e, locations l
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id
SQL> /
ERROR at line 4:
ORA-00904: "D"."LOCATION_ID": invalid identifier

Q. 테이블이 하나이면 조인할 필요가 없으니 처음부터 하나의 테이블 사용하면 되지 않나?

A1. 가능은 하지만 무결성을 보장하기 위해 테이블이 쪼개져

  • 중복제거를 위해 시스템 내부에서 정규화 작업을 해
    • 예) 창고 전체를 그냥 쓰는 게 아니라, 신팔창고 옷창고 참치창고 이렇게 쪼개듯이
    • 반대로 테이블을 하나로 합치는 건 반정규화, 역정규화
  • 테이블을 쪼개서 중복을 제거해. 이러면 중복이 최소화돼
  • 그러다 보니 조인이 많이 발생할 수밖에 없어

A2. 이게 아이러니 한 부분이야

  • 테이블 하나로 합치면 성능 좋지만 무결성 낮아져
  • 무결성, 중복제거를 위해 조인 많아지면 성능 떨어져
  • 이 두 개를 다 무마시키는 방법 --- 돈ㅋㅋㅋ 고사양 컴퓨터 사용


ㅇ 포괄조인 아우터조인 outer join

  • 두 테이블 간 조인 수행에서 조인 기준 열의 어느 한쪽이 NULL이어도 강제로 출력하는 방식
  • 부족한 쪽에 아우터 연산자 (+)를 붙여 NULL NULL 행을 삽입
    (내생각)
    빠짐없이 출력하려는 쪽 반대편에 (+)를 붙이면 될 듯
    공란으로 비워둬도 괜찮은 쪽에 (+) 붙이기

ㅇ 실습 : 우리회사에 근무하는 모든 사원 나열하고 그 사원이 근무하고 있는 부서 이름 출력하기
(사원 빼먹지 않고 출력)

SELECT e.last_name, e.salary, d.department_name
FROM employees e, departments d
WHERE e.department_id=d.department_id (+)

107 rows selected.

  • (+) 없이 그냥 이큐 조인 한다면?

    • 행 106개 나와 (사원수인 107이 아니라)
    • 사원 한 명이 부서 이름이 배당되지 않아서 제외되어 버렸어
    • 즉, 부서 이름이 NULL인 사람은 날라가버려
  • e.department_id (+) = d.department_id 로 한다면?
    (부서 빼먹지 않고 출력)

    • 사원 별 근무 부서가 뜨되
    • 근무하는 사원이 없는 부서까지 모두 출력
    • 122 rows selected. 가 뜸

ㅇ 실습 자료를 해석하는 것이 중요해

  • 122-106=16의 의미 : 사원이 없는 부서 수

    • 122의 의미 : 모든 사원과 + (사원이 없는) 부서까지
    • 106의 의미 : 근무하는 부서가 있는 사원 수
  • 27-16=11의 의미 : 사원이 있는 부서 수

    • 전체 부서 수 27
    • 16의 의미 : 사원이 없는 부서 수

ㅇ 이래서 셀렉트 문장이 어려운 거야.ㅜㅠ
내가 해석할 수 있어야 해.
테이블의 구조를 정확히 이해하고 있어야 한다는 전제가 깔려있어



ㅇ 내부, 외부조인 이름에 대해


profile
STEP BY STEP

0개의 댓글