서로 관계있는 데이터가 여러 테이블로 나뉘어 저장(정규화)되는 RDB 특성상 각 테이블에 저장된 데이터를 효과적으로 검색하기 위해 조인이 필요하다.
조인의 종류
INNER JOIN : 공통 컬럼명 기반으로 결과 집합을 생성
CROSS JOIN (CARTESIAN PRODUCT)
NATURAL JOIN
EQUI JOIN
NON-EQUI JOIN
OUTER JOIN : 조건문에 만족하지 않는 행도 표시
LEFT OUTER
RIGHT OUTER
FULL OUTER
CROSS JOIN
두 테이블을 곱집합
# 아래의 4가지 전부 같은 곱집합을 뜻한다.
select * from player join student;
select * from player cross join student;
select * from player, student;
select * from player inner join student;
INNER JOIN
JOIN의 기본값이 INNER JOIN이라 INNER를 생략 가능.
JOIN 조건에서 동일한 값이 있는 행만 반환
JOIN 조건을 안쓰면 CROSS JOIN이 되기 때문에 JOIN 조건이 필요하다
WHERE 조건절
ON 조건절
컬럼명이 다르더라도 JOIN 조건을 사용할 수 있다.
WHERE 절과의 혼용 가능
JOIN에 사용된 같은 이름의 컬럼을 따로 지정해주지 않고 ‘*’ 처럼 사용한다면, 중복으로 출력된다.
USING 조건절
같은 이름을 가진 컬럼들 중에서 원하는 컬럼에 대해서만 선택적으로 EQUI JOIN 가능
'*' 처럼 별도의 컬럼 순서를 지정하지 않으면 USING 조건절의 기준이 되는 컬럼이 다른 컬럼보다 먼저 출력
JOIN 에 사용된 같은 이름의 컬럼을 하나로 처리
join에 이용된 컬럼은 ALIAS나 테이블 이름과 같은 접두사를 붙일 수 없다. (NATURAL JOIN과 동일)
# WHERE 절 JOIN 조건
select * from player,student where player.name = student.name;
# FROM 절 JOIN 조건
# ON 조건절
select * from player inner join student on player.name = student.name;
# INNER 생략 가능
select * from player join student on player.name = student.name;
# USING 조건절
select * from player join student using(name);
EQUI JOIN
동등비교 (=)를 사용하는 조인
두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방 법으로 대부분 PK ↔ FK 의 관계를 기반으로 한다(모두가 pk,fk기반인 것은 아님)
위의 INNER JOIN에서 동등 비교 조건이 있는 JOIN을 EQUI JOIN이라 볼 수 있다.
NON - EQUI JOIN
동등비교 (=)를 사용하지 않는 조인
Between, >, >=, <, <= 등
SELECT * FROM 테이블1, 테이블2 WHERE 테이블1.칼럼명1 BETWEEN 범위1 AND 범위2;
NATURAL JOIN
두 테이블 간의 동일한 이름을 갖는 모든 컬럼들에 대해 EQUI JOIN 을 수행
추가로 USING 조건절, ON 조건절, WHERE 절에서 JOIN 조건을 정의할 수 없다.
두 테이블 간의 컬럼명이 동일해야 한다 (USING 조건절과 동일)
같은 이름을 가진 컬럼은 한번만 출력된다. (WHERE,ON과 다르다)
JOIN에 이용된 컬럼(=두테이블간 같은 컬럼)은 ALIAS나 테이블 명과 같은 접두사를 붙일 수 없다.
select * from player natural join student;
LEFT OUTER JOIN
= left join
왼쪽 테이블의 모든 데이터 + 왼쪽과 매칭되는 오른쪽 테이블의 레코드를 포함하는 조인
# 1번 이미지
select * from student left join player on player.name = student.name;
# 2번 이미지
select * from player left join student on player.name = student.name;
RIGHT OUTER JOIN
= right join
오른쪽 테이블의 모든 데이터 + 오른쪽과 매칭되는 왼쪽 테이블의 레코드를 포함하는 조인
# 1번 이미지
select * from player right join student on player.name = student.name;
# 2번 이미지
select * from student right join player on player.name = student.name;
FULL OUTER JOIN
left join + right join
= full join
oracle은 full outer join을 지원하는데 mysql은 지원 안하기 때문에 union으로 합쳐주어야 한다
# union 이용해서 left join + right join 한 후 중복 부분 제거
select * from player left join student on player.name = student.name
union
select * from player right join student on player.name = student.name;
# union all 이용해서 left join + right join에서 교집합 제거한 순수 b테이블을 합쳐줌
select * from player left join student on player.name = student.name
union ALL
select * from player right join student on player.name = student.name where player.name is null;
참고사항
union : 여러 개의 sql 결과문에 대한 합집합으로 결과에서 모든 중복된 행은 하나의 행으로 만든다.
union all : union과 같지만 중복된 행을 그대로 출력한다. sql 문의 결과가 중복되지 않는 경우 union과 동일
댓글