테마
조인·서브쿼리·집합 연산
테이블 여러 개의 데이터를 합치는 방법은 세 가지다. 조인(join)은 두 테이블의 행을 옆으로 이어 붙이고, 서브쿼리(subquery)는 한 쿼리의 결과를 다른 쿼리의 조건으로 쓰며, 집합 연산은 두 쿼리의 결과를 위아래로 합친다. 시험은 결과 행 수, 외부 조인(outer join)에서 NULL로 채워지는 행, UNION과 UNION ALL의 차이를 자주 묻는다.
예제 테이블
앞 문서의 학생 테이블(5행, 정새벽만 학과코드 NULL)에 두 테이블을 더한다. 학과는 CS 컴퓨터공학, EE 전자공학, ME 기계공학의 3행이다. ME에는 학생이 없다. 수강은 (학번, 과목) 5행으로 1001-DB, 1001-OS, 1002-DB, 1003-NW, 1005-DB다.
조인
조인은 조건이 맞는 행끼리 이어 한 행으로 만들고, 종류에 따라 짝 없는 행을 버릴지 남길지가 달라진다. 크게 내부 조인(inner join), 외부 조인(outer join), 교차 조인(cross join)으로 나뉘고, 외부 조인은 다시 왼쪽·오른쪽·완전으로 나뉜다.
| 조인 | 결과 | 예제 행 수 |
|---|---|---|
| 내부 조인 | 양쪽 모두 짝이 있는 행만 | 4 |
| 왼쪽 외부 조인 | 왼쪽 전부, 짝 없으면 오른쪽 NULL | 5 |
| 오른쪽 외부 조인 | 오른쪽 전부, 짝 없으면 왼쪽 NULL | 5 |
| 완전 외부 조인 | 양쪽 전부 | 6 |
| 교차 조인 | 모든 조합, 행 수의 곱 | 15 |
행 수는 학생을 왼쪽, 학과를 오른쪽에 두고 ON 학생.학과코드 = 학과.학과코드로 이은 결과다. 내부 조인에서 정새벽은 학과코드가 NULL이라 짝이 없어 빠진다. 왼쪽 외부 조인(left outer join)은 정새벽을 남기고 학과명을 NULL로 채운다. 오른쪽 외부 조인(right outer join)은 학생 없는 ME를, 완전 외부 조인(full outer join)은 둘 다 남긴다. 교차 조인은 조건 없이 5 × 3 = 15행을 만든다.
= 조건으로 잇는 조인을 동등 조인(equi join)이라 하고, <·> 같은 다른 비교까지 포함한 일반 조인을 세타 조인(theta join)이라 한다. 자연 조인(natural join)은 이름이 같은 열로 자동으로 동등 조인하고, 그 열을 결과에 한 번만 보여 준다. JOIN 학과 USING (학과코드)는 잇는 열을 직접 지정하는 동등 조인이다.
서브쿼리
서브쿼리는 괄호 안에 넣은 SELECT이고, 바깥 쿼리가 그 결과를 값이나 목록으로 쓴다. 한 값을 돌려주면 =·>로 비교하고, 여러 값을 돌려주면 IN·ANY·ALL로 비교한다.
WHERE 학번 NOT IN (SELECT 학번 FROM 수강)→ 수강 기록이 없는 최들판.점수 > ALL (서브쿼리)는 목록의 모든 값보다 크다는 뜻이라> MAX(…)와 같다.점수 > ANY (서브쿼리)는 하나라도 보다 크면 참이라> MIN(…)과 같다.
CS 학생 점수(85·70)와 비교하면 > ALL은 박구름(90)만, > ANY는 김하늘·박구름·정새벽을 남긴다.1
집합 연산
집합 연산은 두 SELECT 결과를 위아래로 합친다. 두 쿼리의 열 개수와 자료형이 맞아야 한다. 예로 DB 수강자(1001·1002·1005)와 OS 수강자(1001)를 합쳐 보자.
| 연산자 | 뜻 | 예제 결과 |
|---|---|---|
UNION | 합집합, 중복 제거 | 1001, 1002, 1005 |
UNION ALL | 합집합, 중복 유지 | 4행 |
INTERSECT | 교집합 | 1001 |
EXCEPT | 차집합, 앞 결과에서 뒤 결과 빼기 | 1002, 1005 |
차집합 키워드는 표준 SQL이 EXCEPT이고, Oracle은 19c까지 MINUS만 썼고, 21c부터 EXCEPT도 같은 뜻으로 받는다.
시험 포인트
- 짝 없는 왼쪽 행도 남기기 → LEFT OUTER JOIN. 교차 조인 행 수 → 두 테이블 행 수의 곱.
- 이름이 같은 열로 자동 동등 조인하고 그 열을 한 번만 표시 → NATURAL JOIN.
> ALL=> MAX,> ANY=> MIN.- 중복 제거 UNION, 중복 유지 UNION ALL, 교집합 INTERSECT, 차집합 EXCEPT(Oracle MINUS).
참고
SQLite는
ALL·ANY비교를 지원하지 않아 이 결과는 같은 뜻의MAX·MIN서브쿼리로 실행해 확인했다.ALL·ANY자체는 표준 SQL이고 Oracle·MySQL·PostgreSQL에서 쓸 수 있다. ↩︎
