MySQL

2024.06.05 MySQL 기본 MySQL JOIN

정훈5 2024. 6. 5. 08:58

class_15.sql , class_16.sql , practice0605.sql

class_15.sql
0.00MB
class_16.sql
0.00MB
practice0605.sql
0.00MB

조인(Join) 이란?

데이터베이스에서 조인(Join) 두 개 이상의 테이블에서 관련된 데이터를 결합하여
새로운 결과를 생성할 때 사용하는 중요한 연산입니다.

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) -- 비표준 무시해도 된다.

시나리오 1

 

학생

 

컬럼명 테이터 타입 제약사항 제약사항 설명
no INT NOT NULL, PRIMARY KEY 고유 식별자, NULL 값 불허
name VARCHAR(20) NOT NULL 학생 이름, NULL 값 불허
gender ENUM('F', 'M') NOT NULL 성별, 'F' 또는 'M'만 가능, NULL 값 불허
grade CHAR(1) FOREIGN KEY REFERENCES tb_grade(grade) 다른 테이블의 기본키 참조, 학년 정보

 

성정 등급

컬럼명 데이터 타입 제약사항 제약사항 설명
grade CHAR(1) PRIMARY KEY 학년, 고유 식별자로 기본키 설정
score INT   점수, 별도의 제약사항 없음

 

-- drop table tb_student;
-- drop table tb_grade;
-- drop table tb_registration;

select * from tb_student;

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,
    score int
);

desc tb_student;
desc tb_grade;

select * from tb_student;
select * from tb_grade;

-- 테이블은 정보에 최소 단위 이다.
insert into tb_grade
	values('A', 100),
		  ('B', 80),
	      ('C', 60),
		  ('D', 40),
		  ('E', 20),
		  ('F', 0);

select * from tb_grade;

-- 오류 발생 아래에서 스키마를 추가함 (나이추가 해야됨)
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);
    
-- --------------------------------------
select * from tb_grade;
select * from tb_student;
-- --------------------------------------

-- Join 연산에 ON 절 사용 안해보기 !!!
-- 크로스 JOIN 이 된다.
select *
from tb_student
join tb_grade;

select *
from tb_grade -- 기준
join tb_student; -- 추가로 작업

-- 조인연산을 가능한 ON 절과 함께 사용하자.
-- JOIN 연산 종류 -- INNER JOIN, OUTER JOIN
<aside>
💡 **주의**

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의 결과가 나온다.**

</aside>
-- Join 연산에 ON 절 사용 안해보기 !!!
-- 크로스 JOIN 이 된다.
select *
from tb_student
join tb_grade;

select *
from tb_grade -- 기준
join tb_student; -- 추가로 작업

-- 조인연산을 가능한 ON 절과 함께 사용하자.
-- JOIN 연산 종류 -- INNER JOIN, OUTER JOIN

-- INNER JOIN --> join
select *
from tb_student
join tb_grade on tb_student.grade = tb_grade.grade;

select *
from tb_grade
join tb_student on tb_student.grade = tb_grade.grade;

-- 2단계 (필요한 부분만 가져오기)
-- 속성에서 grade에 대한 정보를 무엇을 가져올지 몰라 오류가 발생한다.
select no, name, grade, age 
from tb_student -- 먼저 접근하는 테이블
join tb_grade -- 조인 하고싶은 테이블
on tb_student.grade = tb_grade.grade;

-- grade 에 tb_student 테이블에서 grade 속성을 가져오라고 지정하였다.
select no, name, tb_student.grade, age
from tb_student -- 먼저 접근하는 테이블
join tb_grade -- 조인 하고싶은 테이블
on tb_student.grade = tb_grade.grade; 

-- 속성에서 tb_student를 s 로 지정하고 tb_grade 를 g로 지정하였고 사용한다.
select s.no, s.name, s.grade, g.score
from tb_student as s
join tb_grade as g
on s.grade = g.grade;

 

먼저 접근하는 테이블이 기준 테이블이 된다.

 

-- 1 단계  LEFT JOIN(= LEFT OUTER JOIN)
select *
from tb_student as s
left join tb_grade as g
on s.grade = g.grade; -- tb_student의 grade 와 tb_grade의 grade 공통된 정보이다.

-- 2 단계
-- 접근하는 기준을 바꿔본다.
select *
from tb_grade as g -- 기준이 되는 테이블
left join tb_student as s -- 조인인 되는 테이블
on g.grade = s.grade; -- tb_grade의 grade 와 tb_student의 grade 공통된 정보이다.

desc tb_student;

 

LEFT JOIN 먼저 접근하는 테이블이 기준 테이블이 된다 .

 

RIGHT JOIN(= RIGHT OUTER JOIN)

오른쪽 테이블을 기준으로 합치며, 나머지 부분은 LEFT JOIN과 같다.

-- 1단계 RIGHT JOIN(= RIGHT OUTER JOIN)
select *
from tb_student as s -- 기준이 되는 테이블
right join tb_grade as g -- 조인인 되는 테이블
on s.grade = g.grade; -- tb_grade의 grade 와 tb_student의 grade 공통된 정보이다.