T'SPACE

다채로운 에디터들의 이야기

컴퓨터공학/데이터베이스 DB

외부 조인과 내부 조인 Inner Join and Outer Join

Tonny Kang 2024. 10. 20. 07:37
반응형

JOIN 표현식


다중 테이블에 대한 쿼리


왜 우리는 다중 테이블을 사용할까요?

단일 테이블:

  • 데이터 교환(공유)이 더 쉽습니다
  • 하지만 데이터 중복, 이상 현상, 확장성, 유연성 문제가 있습니다

다중 테이블:

  • 데이터 업데이트가 더 쉽습니다
  • 각 개별 테이블에 대한 쿼리가 더 빠릅니다

다중 테이블에 대한 쿼리는 다음과 같이 구현할 수 있습니다:

  • FROM 절에 테이블을 나열
  • 동일한 이름의 속성이 있는 경우, "<관계>.<속성>"을 사용

→ Cartesian Product 카티션 곱(Cross join), Join

SELECT name
FROM Student, Enrolled
WHERE sid = student_id
반응형

Cartesian Product 카티션 곱 (Cross Join)


두 관계에 동일한 이름의 필드가 있는 경우, 속성 이름에 해당 속성이 원래 속한 관계의 이름이 추가됩니다

기본 조인은 Cross Join이지만 명시적으로 이름을 지정할 수 있습니다

SELECT name
FROM Student cross join Enrolled
WHERE sid = student_i

또한 이렇게 작성할 수도 있습니다

SELECT name
FROM Students JOIN Enrolled ON sid = student_id

튜플 변수


때로는 속성이 어느 테이블에서 왔는지 구분하기 어려울 수 있습니다

SELECT Student.name
FROM Student, Enrolled
WHERE sid = student_id
SELECT S.name
FROM Student S, Enrolled E
WHERE S.sid = E.student_id

실행 순서 (Cross Join)


  1. FROM : 크로스 프로덕트 수행
  2. WHERE: 조건 적용
  3. SELECT: 프로젝션 적용
728x90

JOIN


Natural Join


  • 공통 속성을 기반으로 조인
  • 결과에서 중복되는 공통 속성 제거

  • 각 공통 열의 복사본은 하나만 유지됩니다
SELECT a1, a2
FROM r1 NATURAL JOIN teaches;
  • 동일한 이름을 가진 관련 없는 속성이 잘못 동등화되는 것을 주의하세요
  • 이를 피하기 위해 "USING"을 사용하여 어떤 열이 동등화되어야 하는지 지정할 수 있습니다
SELECT a1, a2
FROM (r1 NATURAL JOIN teaches) JOIN r3 using(common attribute);

 

Q. 다음에 대해서는 어떨까요


→ 학생들이 실제로 수강한 과목만 반환됩니다

자연 조인의 결합법칙 때문에 이들은 동등합니다 -> Associative Law

Inner Join vs Outer Join


내부 조인은 조건을 충족하는 행만 남습니다 → 교집합

 

외부 조인의 경우

일부 관계는 모든 행을 유지합니다

  • Left (outer) join
  • Right (outer) join
  • Full (outer) join : 합집합

다음은 Inner Join의 구현입니다

SELECT name
FROM Students JOIN Enrolled ON sid = student_id

SELECT name
FROM Students INNER JOIN Enrolled 
ON sid = student_id
SELECT name
FROM Students FULL OUTER JOIN Enrolled 
ON sid = student_id
SELECT name
FROM Students LEFT OUTER JOIN Enrolled 
ON sid = student_id
SELECT name
FROM Students RIGHT OUTER JOIN Enrolled 
ON sid = student_id

OUTER 키워드는 생략할 수 있습니다

WHERE와 ON의 차이점


첫 번째 코드의 결과는 다음과 같습니다

name course
Mary 354
Tom 354
Jack NULL

왜냐하면 이는 left join이기 때문입니다

하지만 두 번째 코드의 경우

결과는 다음과 같습니다

name course
Mary 354
Tom 354

왜냐하면 WHERE 명령이 course가 NULL인 행을 제거하기 때문입니다

조인에 대한 집합 연산자 등가성 (같은 SQL 구현)


SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and (e.cid=354 or e.cid=454)

는 다음과 동일합니다

SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and cid=454
UNION
SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and cid=354

SELECT name
FROM Students S, Enrolled E1, Enrolled E2
WHERE S.sid = E1.student_id AND S.sid = E2.student_id
            AND (E1.cid=354 AND E2.cid=454)

는 다음과 동일합니다

SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and cid=454
INTERSECT
SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and cid=354

중복을 유지하려면 ALL을 사용하세요

SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and cid=454
INTERSECT ALL
SELECT name
FROM Students s, Enrolled e
WHERE s.sid=e.student_id and cid=354

ALL


UNION

INTERSECT

EXCEPT

행이 첫 번째 쿼리에서 여러 번 나타나고 두 번째 쿼리에서 더 적게 나타나거나 전혀 나타나지 않는 경우, 결과에는 첫 번째 쿼리에 나타나는 횟수에서 두 번째 쿼리에 나타나는 횟수를 뺀 만큼 해당 행이 포함됩니다.

반응형