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)
- FROM : 크로스 프로덕트 수행
- WHERE: 조건 적용
- SELECT: 프로젝션 적용
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
행이 첫 번째 쿼리에서 여러 번 나타나고 두 번째 쿼리에서 더 적게 나타나거나 전혀 나타나지 않는 경우, 결과에는 첫 번째 쿼리에 나타나는 횟수에서 두 번째 쿼리에 나타나는 횟수를 뺀 만큼 해당 행이 포함됩니다.
'컴퓨터공학 > 데이터베이스 DB' 카테고리의 다른 글
Correlated Subquery 상관 서브쿼리 (2) | 2024.10.22 |
---|---|
SQL 서브쿼리 Subquery (1) | 2024.10.21 |
기초 SQL문 정리 SFW, HAVING, GROUP BY ... (8) | 2024.10.19 |
데이터베이스 SQL DDL과 DML (5) | 2024.10.18 |
데이터베이스 Relational Algebra 관계 대수 (3) | 2024.10.15 |