티스토리 뷰
04-2. 두 테이블을 묶는 조인
조인(join)
조인이란 두 개의 테이블을 서로 묶어서 하나의 결과를 만들어 내는 것을 말한다.
(두 테이블을 엮어서 정보를 추출한다.)
내부 조인
내부 조인은 두 테이블을 연결할 때 가장 많이 사용되는 것으로 되게 조인이라고 하면 내부 조인을 의미한다.
조인은 일대다(1:N) 관계로 연결되어야 한다.
여기서 1은 PK(기본키), N은 FK(외래키)로 보통 사용을 한다.
내부 조인의 기본
select <열(컬럼) 목록>
from <첫번째 테이블>
inner join <두번째 테이블>
on <조인될 조건>
[where 검색 조건]
* inner join은 그냥 join으로 입력해도 상관 없음
구매 테이블에서 GRL이라는 아이디를 가진 사람이 구매한 물건을 발송하기 위해 필요한 정보들을 조인을 통해 모두 검색할 수 있다. 정보들을 검색하기 위해 buy 테이블과 member 테이블을 inner join하여 조회했다.
이때 기준이 되는 테이블은 from 뒤에 있는 buy 테이블이다.
또한, 쿼리문이 실행될때 순서가 존재한다.
inner join을 제외한 select ~ from ~ where 문으로 조회를 한 후 inner join 문이 실행되어 아래와 같이 결과가 도출된다.
select * from buy inner join member on buy.mem_id = member.mem_id where buy.mem_id='GRL';
-- select from where 먼저 수행 후 inner join하여 조인함
도출된 결과를 보면 mem_id가 GRL인 모든 정보를 조회하는 것을 볼 수 있다.
조인 시 where 조건 없이도 출력을 할 수 있다.
그리고 from 뒤에 오는 테이블명에 따라 출력되는 결과가 다른데 그것은 from 뒤에 명시되는 테이블이 조인의 기준이되기 때문이다.
테이블에 같은 mem_id가 여러 개인 경우 같은 mem_id로 여러개가 출력된다.
만약 일치하는 mem_id가 없는 경우는 출력이 되지 않는다.( inner join은 교집합만 출력함)
* 내부 조인은 두 테이블에 모두 있는 내용만 출력됨 (교집합만 출력)
만약, 한쪽이라도 있는 내용을 출력하고싶을 때는 외부조인을 사용해야한다. (or과 같이 사용된다.)
buy 테이블을 기준으로 하는 쿼리문
select * from buy inner join member on buy.mem_id = member.mem_id;
member 테이블을 기준으로 하는 쿼리문
select * from member inner join buy on buy.mem_id = member.mem_id;
내부 조인의 간결한 표현
열이 많아 복잡해 보일 수 있다 그렇기 때문에 특정 컬럼만 추출을 할 수 있다.
아래와 같이 출력을 할 수 있는데
이때 주의할 점이 있다.
mem_id의 경우 buy 테이블과 member 테이블 두개의 테이블에 모두 존재한다.
그렇기 때문에 mem_id라고 작성되면 어디 테이블의 mem_id인지 구별을 할 수 없다.
구별을 하기 위해 '테이블명.컬럼명'으로 작성해주어야한다.
아래는 그것의 예시이다.
mem_id를 구분하기 위해 buy.mem_id라고 작성한 것을 볼 수 있다.
select buy.mem_id, mem_name, prod_name, addr, concat(phone1,phone2) '연락처' from buy inner join member on buy.mem_id = member.mem_id;
모든 칼럼 앞에 테이블명을 작성해주어도 괜찮다.
이렇게 되면 좀 더 명확하게 컬럼을 구분할 수 있다.
select buy.mem_id, member.mem_name, buy.prod_name, member.addr, concat(member.phone1, member.phone2) '연락처' from buy inner join member on buy.mem_id = member.mem_id;
위 처럼 테이블명. 을 작성해주어도 되지만 따로 alias(별칭)을 작성해주어도 괜찮다.
buy B member M으로 하여 buy의 별칭은 B , member의 별칭은 M으로 정해주었다.
그리고 컬럼명 앞에 해당 테이블의 별칭을 붙여주어 간결하게 사용할 수 있다.
select B.mem_id, M.mem_name, B.prod_name, M.addr, concat(M.phone1, M.phone2) '연락처' from buy B inner join member M on B.mem_id = M.mem_id;
위의 세개 쿼리문의 결과는 아래와 같이 동일하게 도출된다.
중복된 결과 1개만 출력하기
내부 조인을 사용시 양쪽에 모두 있는 내용이 여러개 일 경우 동일한 값들이 추출된다.
하지만 동일한 값이 필요 없는 경우도 존재한다.
그럴 경우 중복을 없애고자하는 컬럼명 앞에 distinct 를 작성하면 중복된 값들을 제거한 후 정보를 추출할 수 있다.
select distinct M.mem_id, M.mem_name, M.addr, concat(M.phone1, M.phone2) '연락처' from buy B inner join member M on B.mem_id = M.mem_id;
아래는 distinct를 사용한 결과이다.
구매 회원에게 문자를 보내고자하는 경우 구매는 여러번 가능하기 때문에 같은 회원이 여러개 구매할 수 도 있는데 그럴 경우 중복을 없애 구매한 회원을 추출하고 문자를 발송하는데 사용하기 유용하다.
외부조인
외부 조인은 한쪽에만 데이터가 있어도 결과를 추출할 수 있다.
(내부 조인은 양쪽에 데이터가 존재해야만 결과 추출 가능)
외부 조인의 기본
외부 조인에는 left outer join / right outer join / full outer join 이 있다.
select <열 목록>
from <첫번째 테이블 (left 테이블)>
<left|right|full> outer join <두번째 테이블(right 테이블)>
on <조인될 조건>
[where 검색 조건];
left outer join 문
left outer join문은 왼쪽 테이블을 기준으로 하여 왼쪽 테이블의 내용은 모두 출력한다.
select M.mem_id, M.mem_name, B.prod_name, M.addr from member M left outer join buy B on M.mem_id = B.mem_id order by M.mem_id;
where 조건 추가 is null
join 시 where 조건을 추가하여 조인을 할 수 있다.
아래는 where B.prod_name is null이라는 조건을 작성하여 한번도 구매를 한 적 없는 회원을 추출하는 쿼리문이다.
where 조건을 작성할 때는 join 문이 끝난 후 작성된다.
select M.mem_id, M.mem_name, B.prod_name, M.addr from member M left outer join buy B on M.mem_id = B.mem_id where B.prod_name is null order by M.mem_id;
Right outer join 문
right outer join은 left와 다르게 오른쪽에 있는 값을 기준으로 한다.
그렇기 때문에 동일한 결과를 출력하려면 오른쪽 테이블과 왼쪽 테이블의 위치를 바꾸면 동일한 결과를 출력할 수 있다.
select M.mem_id, M.mem_name, B.prod_name, M.addr from buy B right outer join member M on M.mem_id = B.mem_id order by M.mem_id;
Full outer join 문
left join 과 right join을 합친 것으로 모든 내용을 다 출력한다.
cross join과 비슷해 보이지만 다르다.
* full outer join과 cross join의 차이점
full outer join은 두 테이블의 모든 레코드를 반환하지만 조건에 맞는 레코드가 없는 경우에는 null 값을 반환한다.
cross join은 null값이라도 반환한다. 예를 들어 A에는 2개의 레코드 B에는 3개의 레코드가 있는 경우 2X3 = 6개의 레코드가 반환된다.
기타 조인
내부 조인과 외부 조인 말고도 상호 조인과 자체 조인도 있다.
상호 조인
상호 조인은 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시킨다.
그래서 상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 개수가 된다.
select * from buy cross join member;
자체 조인
지금까지의 조인은 모두 2개의 테이블을 조인했다. 하지만 자체 조인은 자신이 자신과 조인한다.
그래서 2개의 테이블이 필요하지 않고 1개의 테이블만 있으면 된다.
select <열 목록>
from <테이블> 별칭A
inner join <테이블> 별칭B
on <조인될 조건>
[where 검색 조건]
자체 조인은 동일한 테이블을 사용하므로 별칭으로 구분한다.
별칭 A는 검색 대상 B는 검색 값으로 구분한다.
'코딩 > SQL' 카테고리의 다른 글
[13주 5일차] 인덱스 (0) | 2024.01.05 |
---|---|
[13주 4일차] 테이블과 뷰 (2) | 2024.01.04 |
[13주 3일차] SQL 기본 문법 (1) | 2024.01.03 |
[13주 3일차] SQL 고급 문법 (1) | 2024.01.03 |
[13주 2일차] SQL 기본 문법 (0) | 2024.01.02 |
- Total
- Today
- Yesterday