조인 Join
데이터베이스에서 조인은 두 개 이상의 테이블에서 관련된 데이터를 결합하여 새로운 결과를 생성할 때 사용하는 중요한 연산이다.
데이터베이스에서 정보는 중복을 최소화하고 효율적으로 저장하기 위해 여러 테이블에 분산되어 저장된다. 실제로 정보를 사용할 때는 여러 테이블에 흩어져 있는 데이터를 통합해야 할 필요가 발생할 수 있다. 예를 들면 어떤 학생이 어떤 수업을 듣고 있는지 알고 싶을 때, '학생' 테이블과 '수업' 테이블을 결합해야만 필요한 정보를 얻을 수 있다. 복잡한 질의를 수행하기 위해서는 종종 여러 테이블의 데이터를 결합하고 비교해야 한다. 조인을 사용하면 이러한 요구사항을 효과적으로 처리할 수 있다.
항상 먼저 접근하는 테이블이 기준이 되는데, 위 그림을 기준으로 왼쪽 동그라미가 그에 해당한다.
- JOIN은 크게 INNER JOIN과 OUTER JOIN으로 분류된다.
- INNER JOIN은 조건에 해당하는 데이터만 뽑아낸다.
- OUTER JOIN 에는 다음과 같이 분류되지만, MySQL에서는 FULL OUTER JOIN을 지원하지 않는다.
- LEFT OUTER JOIN
- RIGHT OUTER JOIN
- FULL OUTER JOIN (MySQL에서는 지원 X)
주의
MySQL에서 JOIN, CROSS JOIN, INNER JOIN은 구문적으로 동등하다. 결과가 같고, 서로 대체 가능하다. (표준 SQL에서는 동일하지 않다. 보통 INNER JOIN은 ON절과 함께 쓰이고, CROSS JOIN은 다르게 사용된다. CROSS JOIN이란 한 쪽 테이블의 행 하나에 다른 쪽 테이블의 행을 각각 조인시키는 걸 말한다.) ON 조건 없이 사용하게 되면 CROSS JOIN의 결과가 나오고, ON 조건을 사용하게 되면 조건을 건 컬럼의 값이 같은 데이터들을 합친 결과가 나온다.
MySQL에서는 JOIN 또는 INNER JOIN을 할 때, ON 으로 조건을 지정해주지 않으면 CROSS JOIN의 결과가 나온다.
create table tb_student(
no int not null primary key,
name varchar(20) not null,
gender enum('F', 'M') not null,
grade char(1),
foreign key(grade) references tb_grade(grade)
);
create table tb_grade(
grade char(1) primary key,
socore int
);
select * from tb_grade;
-- 테이블은 정보에 최소 단위 이다.
insert into tb_grade values ('A', 100);
insert into tb_grade values ('B', 80);
insert into tb_grade values ('C', 60);
insert into tb_grade values ('D', 40);
insert into tb_grade values ('E', 20);
insert into tb_grade values ('F', 0);
-- 오류 발생 아래에서 스키마 추가
-- insert into tb_student(no, name, gender, grade, age) values('100', '길동', 'F', 25, 'B');
-- 스키마 구조 변경이 필요하다.
alter table tb_student add age int;
select * from tb_student;
insert into tb_student(no, name, gender, grade, age)
values('100', '길동', 'F', 'A', 35);
insert into tb_student(no, name, gender, grade, age)
values('200', '둘리', 'M', 'B', 25);
insert into tb_student(no, name, gender, grade, age)
values('300', '마이콜', 'F', 'B', 15);
insert into tb_student(no, name, gender, grade, age)
values('400', '야스오', 'M', 'C', 25);
insert into tb_student(no, name, gender, grade, age)
values('500', '티모', 'F', 'E', 25);
-- JOIN 연산에 ON 절 사용 안해보기 !!!
-- 크로스 조인이 된다. !!!
select *
from tb_student
join tb_grade;
select *
from tb_grade
join tb_student;
-- 조인연산은 가능한 ON 절과 함께 사용하자.
-- JOIN --> INNER JOIN, OUTER JOIN
-- INNNER JOIN --> join
-- 1 단계
select *
from tb_student
join tb_grade on tb_student.grade = tb_grade.grade;
-- 2 단계 (필요한 부분만 가져오기)
select s.no, s.name, s.grade, s.age, g.socore
from tb_student as s
join tb_grade as g
on s.grade = g.grade;
OUTER JOIN
LEFT JOIN ( = LEFT OUTER JOIN)
왼쪽 테이블을 기준으로 합치며, ON 절에 있는 조건 컬럼의 값이 같은 데이터를 합친다. 오른쪽 테이블에 값이 같은 데이터가 없다면, NULL이 삽입된다.
-- 1 단계
select *
from tb_student as s
left join tb_grade as g
on s.grade = g.grade;
-- 2 단계
select *
from tb_grade as g
left join tb_student as s
on g.grade = s.grade;
RIGHT JOIN ( = RIGHT OUTER JOIN)
오른쪽 테이블을 기준으로 합치며, 나머지 부분은 LEFT JOIN과 같다.
-- LEFT OUTER JOIN
-- 1 단계
select *
from tb_student as s
left join tb_grade as g
on s.grade = g.grade;
-- 2 단계
select *
from tb_grade as g
left join tb_student as s
on g.grade = s.grade;
desc tb_student;
-- RIGHT OUTER JOIN
select *
from tb_student as s
right join tb_grade as g
on s.grade = g.grade;
'MySQL' 카테고리의 다른 글
subquery 서브 쿼리 (2) | 2024.06.13 |
---|---|
Function (0) | 2024.06.11 |
INDEX (0) | 2024.06.11 |
KEY (0) | 2024.06.11 |
table CRUD (3) | 2024.06.11 |