코딩 스터디

Schema 구현 및 INNER JOIN과 OUTER JOIN

hunm719 2023. 2. 1. 22:03

오늘 실습한 SQL 및 Schema 과제 중 일부를 복습해보자

 

테이블 이미지

 

먼저 위의 테이블들을 intellij에서 schema.sql파일에 구현했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
CREATE TABLE `user` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255not NULL,
  `email` varchar(255not NULL
);
 
CREATE TABLE `content` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `title` varchar(255not NULL,
  `body` varchar(255not NULL,
  `created_at` timestamp not NULL DEFAULT CURRENT_TIMESTAMP,
  `userId` int,
  FOREIGN KEY (`userId`REFERENCES `user` (`id`)
);
 
 
CREATE TABLE `category` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255not NULL
);
 
CREATE TABLE `role` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255not NULL
);
 
CREATE TABLE `content_category` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `contentId` int,
  FOREIGN KEY (`contentId`REFERENCES `content` (`id`),
  `categoryId` int,
  FOREIGN KEY (`categoryId`REFERENCES `category` (`id`)
);
 
ALTER TABLE user ADD roleId int;
ALTER TABLE user ADD FOREIGN KEY (roleId) REFERENCES role (id);
cs

schema.sql파일을 구현할 때 가장 신경써야 했던 부분은 코드 흐름에 맞게  작성해야만 모든 table을 인식한다는 점이었다.

 

처음 파일을 구현할 때 아래와 같이 user 테이블 안에 roleId-pk를 같이 구현했었다. 

1
2
3
4
5
6
7
CREATE TABLE `user` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255not NULL,
  `email` varchar(255not NULL,
  `roleId` int,
  FOREIGN KEY (`roleId`REFERENCES 'role' (`id`);
);
cs

코드의 흐름은 기본적으로 위에서 아래로 내려가기 때문에 6번째 줄에서는 role 테이블이 구현되어 있지 않으므로 에러가 생길 수 밖에 없었다.

이를 인지하고 role 테이블을 생성한 후에 ALTER를 통해 user테이블을 수정했고, 문제를 해결했다.

(지금 와서 든 생각이지만 role테이블을 생성하고 바로 아래에 user테이블을 수정하는게 가독성이 좀 더 좋지 않을까 싶다.)

 

 

 

다음은 SQL을 작성해보는 문제 중 JOIN과 관련된 문제를 추려보았다.

 

1번 문제
content의 title과 그 컨텐츠를 작성한 user의 name을 찾기 위한 SQL을 작성해주세요.
    - 저자가 없더라도, 컨텐츠의 title을 모두 찾아야합니다.

문제풀이

(1)SQL목적 - content.title 과 user.name 을 찾기 : SELECT 사용

(2)content와 user는 서로 user.id와 content.userId로 연결되어 있음(교집합이 존재) : JOIN 사용

(3)저자가 없더라도 컨텐츠의 title을 모두 찾아야 한다 = content.userId의 값이 null이라도 content.title 을 찾아야한다 = INNER JOIN 과 OUTER JOIN 중 OUTER JOIN을 사용

 

1
2
3
4
SELECT content.title, user.name
FROM content
LEFT JOIN user
ON content.userId = user.id;
cs

 

2번 문제
minsanggu이 작성한 content의 category name을 찾기위한 SQL을 작성해주세요.

문제풀이

(1)SQL목적 - category.name 을 찾기 : SELECT 사용

(2)user, content, content_category, category는 연결되어 있음 : JOIN 사용

(3)minsanggu가 작성한 category name을 찾아야 한다 = INNER JOIN을 계속 연결하여 user.name = 'minsanggu'로 마무리

 

1
2
3
4
5
6
7
8
SELECT category.name FROM category
JOIN content_category
ON content_category.categoryId = category.id
JOIN content
ON content.id = content_category.contentId
JOIN user
ON user.id = content.userId
WHERE user.name = 'minsanggu';
cs

+ 다음부턴 일일이 적지 말고 AS를 활용하자

예) SELECT cg.name FROM category AS cg

 

 

 

이번 과제로 SQL 문법과 스키마를 많이 공부할 수 있었다.

역시 내 손으로 코드를 직접 타이핑하면서 공부하는 것이 가장 빨리 익숙해진다는 걸 다시금 느낄 수 있었다.