๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
TIL -์ผ๊ฐ„ํ•™์Šต๊ธฐ๋ก/๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค

[SQL] im-sprint-learn-sql

by ___Jin 2022. 3. 9.

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ธ SQL์„ ๊ณต๋ถ€ํ–ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด CRUD๋ฅผ ํ• ์ˆ˜์žˆ๋Š” ์–ธ์–ด์ธ SQL ๋ฌธ๋ฒ•์„ ์Šคํ”„๋ฆฐํŠธ ๊ธฐ์ค€์œผ๋กœ ์ •๋ฆฌํ•ด๋ณด์ž.

 

์Šคํ”„๋ฆฐํŠธ๋Š” part 5๊นŒ์ง€ ์žˆ๊ณ ,

part1,2๋Š” mysql ํ€ด์ฆˆ์™€ ์„ค์น˜๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์–ด ์–ด๋ ต์ง€ ์•Š์œผ๋ฏ€๋กœ part3๋ถ€ํ„ฐ ๋‹ค๋ฃจ๊ธฐ๋กœ ํ•œ๋‹ค.

 

Part 3์˜ ๋ชฉํ‘œ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ , ์ฃผ์–ด์ง„ ์Šคํ‚ค๋งˆ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก SQL ๋ฌธ ์ž‘์„ฑ.

vscode์—์„œ ๊ณผ์ œ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ์— ์•ž์„œ ์„ค์น˜ํ•ด๋‘”mysql์— ์ ‘์†ํ•ด์•ผ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋ฅผ ํ†ต๊ณผํ• ์ˆ˜์žˆ๋‹ค.

/migrations/schema.sql

์ด๋ฒˆ ์Šคํ”„๋ฆฐํŠธ์˜ ํ•ต์‹ฌ์ด๊ณ , ๋ฐ˜๋“œ์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„. ํ…Œ์ด๋ธ”๊ณผ ์ปฌ๋Ÿผ์„ ์ƒ์„ฑํ•ด์•ผ ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ• ์ˆ˜์žˆ๋‹ค.

๋งŒ๋“ค์–ด์•ผํ•˜๋Š” ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ๋ฅผ ๋ณด๊ณ  ํ•„์š”ํ•œ๋ถ€๋ถ„์„ ์ฑ„์šด๋‹ค

 

users, content ์Šคํ‚ค๋งˆ

 

USE learnmysql;

/* DESIGN SCHEMA FOR REQUIREMENT */

-- PART 3:
-- ์—ฌ๊ธฐ user ํ…Œ์ด๋ธ” ์ƒ์„ฑ SQL ๊ตฌ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 
-- user ํ…Œ์ด๋ธ”์„ ์ฐธ๊ณ ํ•ด์„œ, content ํ…Œ์ด๋ธ” ์ƒ์„ฑ SQL ๊ตฌ๋ฌธ์„ ์™„์„ฑํ•˜์„ธ์š”.

CREATE TABLE `user` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255) not NULL,
  `email` varchar(255) not NULL
);

CREATE TABLE `content` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `title` varchar(255) not NULL,
  `body` varchar(255) not Null,
  `created_at` timestamp not NULL DEFAULT CURRENT_TIMESTAMP,
  `userId` int,
  FOREIGN KEY (`userId`) REFERENCES `user` (`id`)
);โ€‹

schema.sql์„ ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ๋’ค part3.js๋กœ ๋„˜์–ด๊ฐ€์ž.

TODO: Q 3-1. ํ˜„์žฌ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ํ…Œ์ด๋ธ” ์ •๋ณด๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.

const PART3_1 = `SHOW TABLES`;

TODO: Q 3-2. user ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” user ํ…Œ์ด๋ธ”์„ ์ž‘์„ฑํ•ด์•ผ๋งŒ, ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.

const PART3_2 = `describe user`;

TODO: Q 3-3. content ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” content ํ…Œ์ด๋ธ”์„ ์ž‘์„ฑํ•ด์•ผ๋งŒ, ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.
const PART3_3 = `describe content`;

Part 4๋Š” Part 3์—์„œ ๊ตฌ์„ฑํ•œ ์Šคํ‚ค๋งˆ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก SQL ๋ฌธ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ

TODO: Q 4-1. user ํ…Œ์ด๋ธ”์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์ปฌ๋Ÿผ์„ ํฌํ•จํ•œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART4_1 = `select * from user`;

TODO: Q 4-2. user ํ…Œ์ด๋ธ”์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์—์„œ name ์ปฌ๋Ÿผ๋งŒ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART4_2 = `select name from user`;

TODO: Q 4-3. user ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART4_3 = `INSERT INTO user (name, email) VALUES ('WOODY', 'woody@naver.com')`;

TODO: Q 4-4. user ํ…Œ์ด๋ธ”์—์„œ ํŠน์ • ์กฐ๊ฑด์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์กฐ๊ฑด : name์ด duhyunkim์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
const PART4_4 = `SELECT name FROM user WHERE user.name ='duhyunkim'`;

TODO: Q 4-5. user ํ…Œ์ด๋ธ”์—์„œ ํŠน์ • ์กฐ๊ฑด์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์กฐ๊ฑด : name์ด duhyunkim์ด ์•„๋‹ˆ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
const PART4_5 = `SELECT name FROM user WHERE NOT user.name = 'duhyunkim'`;

TODO: Q 4-6. content ํ…Œ์ด๋ธ”์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์—์„œ title ์ปฌ๋Ÿผ๋งŒ์„ ์ฐพ๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART4_6 = `SELECT title FROM content`;

TODO: Q 4-7. content์˜ title๊ณผ ๊ทธ ์ปจํ…์ธ ๋ฅผ ์ž‘์„ฑํ•œ user์˜ name์„ ์ฐพ๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์ €์ž๊ฐ€ ์—†๋”๋ผ๋„, ์ผ„ํ„ด์ธ ์˜ title์„ ๋ชจ๋‘ ์ฐพ์•„์•ผํ•ฉ๋‹ˆ๋‹ค.
const PART4_7 = `SELECT content.title, user.name FROM user INNER JOIN content ON user.id = content.id`;

TODO: Q 4-8. content์˜ title๊ณผ ๊ทธ ์ปจํ…์ธ ๋ฅผ ์ž‘์„ฑํ•œ user์˜ name์„ ์ฐพ๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์ €์ž๊ฐ€ ์žˆ๋Š” ์ปจํ…์ธ ์˜ title๋งŒ ์ฐพ์•„์•ผํ•ฉ๋‹ˆ๋‹ค.
const PART4_8 = `
SELECT content.title, user.name 
FROM user 
INNER JOIN content ON user.id = content.id 
WHERE content.userId `;

TODO: Q 4-9. content์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - title์ด database sprint์ธ content ๋ฐ์ดํ„ฐ์—์„œ body๋ฅผ database is very easy๋กœ ์ˆ˜์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
const PART4_9 = `UPDATE content
SET body = 'database is very easy'
WHERE title = 'database sprint'`;

TODO: Q 4-10. content์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - duhyunkim์ด ์ž‘์„ฑํ•œ ์ปจํ…์ธ ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”. ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ์€ ์ž์œ ์ž…๋‹ˆ๋‹ค. (์ฐธ๊ณ : duhyunkim์˜ ์•„์ด๋””๋Š” 1์ž…๋‹ˆ๋‹ค.)
const PART4_10 = `
INSERT INTO content(title, body, userId) 
VALUES ('ํž˜๋‚ด์š”', 'ํ†ต๊ณผ' , '1')
`;

 

Part 5๋Š” ์š”๊ตฌ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์Šคํ‚ค๋งˆ๋ฅผ ์ถ”๊ฐ€/๋ณ€๊ฒฝํ•˜๊ณ , ์ถ”๊ฐ€/๋ณ€๊ฒฝ๋œ ์Šคํ‚ค๋งˆ๋ฅผ ํ™•์ธํ•˜๋Š” ๊ณผ์ •.

1:N(์ผ๋Œ€๋‹ค), N:N(๋‹ค๋Œ€๋‹ค) ๊ด€๊ณ„์™€ ๋”๋ถˆ์–ด JOIN ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด ์ดํ•ดํ•˜๊ธฐ

 

๋จผ์ €,

/migrations/schema.sql์— ํ…Œ์ด๋ธ”์„ ์ถ”๊ฐ€ ๋ฐ ์ˆ˜์ •ํ•ด์ค€๋‹ค.

๊ธฐ์กด์˜ ์ž‘์„ฑ ํ…Œ์ด๋ธ” ํ† ๋Œ€๋กœ ์ž‘์„ฑ 

 

TODO: Q 5-1-1. category ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_1_1 = `describe category`;

TODO: Q 5-1-2. content_category ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_1_2 = `DESCRIBE content_category`;

TODO: Q 5-1-3. role ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_1_3 = `DESCRIBE role`;

TODO: Q 5-1-4. user ํ…Œ์ด๋ธ”์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_1_4 = `DESCRIBE user`;

TODO: Q 5-2-1. category ํ…Œ์ด๋ธ”์— ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ์—์„œ id, name์„ ์ฐพ๋Š” SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_1 = `select id, name from category`;

TODO: Q 5-2-2. user์˜ name๊ณผ email ๊ทธ๋ฆฌ๊ณ  ๊ทธ user๊ฐ€ ์†ํ•œ role name(์ปฌ๋Ÿผ๋ช…: roleName)์„ ์ฐพ๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
        - ์†ํ•œ role์ด ์—†๋”๋ผ๋„, user์˜ name๊ณผ email,role name์„ ๋ชจ๋‘ ์ฐพ์•„์•ผํ•ฉ๋‹ˆ๋‹ค.
const PART5_2_2 = 
`SELECT user.name, user.email, role.name AS roleName
FROM user
LEFT JOIN role ON user.roleId = role.id`;

TODO: Q 5-2-3. ์–ด๋Š role์—๋„ ์†ํ•˜์ง€ ์•Š๋Š” user์˜ ๋ชจ๋“  ์ปฌ๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_3 = `SELECT * FROM user WHERE roleId IS NULL`;

TODO: Q 5-2-4. content_category ํ…Œ์ด๋ธ”์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์นผ๋Ÿผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_4 = `SELECT * FROM content_category`;

TODO: Q 5-2-5. jiSungPark์ด ์ž‘์„ฑํ•œ content์˜ title์„ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_5 = `
SELECT content.title, user.name 
FROM user 
INNER JOIN content ON user.id = content.id 
WHERE user.name = 'jiSungPark'`;

TODO: Q 5-2-6. JiSungPark์ด ์ž‘์„ฑํ•œ content์˜ category name์„ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_6 = `
SELECT user.name, category.name
FROM user
INNER JOIN content ON user.id = content.userId
INNER JOIN content_category ON content_category.contentId = content.id
INNER JOIN category ON content_category.categoryId = category.id
WHERE user.name = 'jiSungPark'`;

TODO: Q 5-2-7. category์˜ name์ด soccer์ธ content์˜ title, body, created_at์„ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_7 = `
SELECT content.title, content.body, content.created_at
FROM content
JOIN content_category ON content.Id = content_category.contentID
JOIN category ON categoryId = category.id
WHERE category.name = 'soccer'`;

TODO: Q 5-2-8. category์˜ name์ด soccer์ธ content์˜ title, body, created_at, user์˜ name์„ ์ฐพ๊ธฐ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_8 = `
SELECT content.title, content.body, content.created_at, user.name
FROM user
JOIN content ON user.id = content.userId
JOIN content_category ON content.Id = content_category.contentID
JOIN category ON categoryId = category.id
WHERE category.name = 'soccer'`;

TODO: Q 5-2-9. duRiCha๊ฐ€ ์ž‘์„ฑํ•œ ๊ธ€์˜ ๊ฐœ์ˆ˜ (์ปฌ๋Ÿผ๋ช…: ContentCount)๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_9 = `
SELECT COUNT(content.title) AS ContentCount 
FROM user
JOIN content ON user.id = content.userId
WHERE user.name = 'duRiCha';`;

TODO: Q 5-2-10. ๊ฐ user(์ปฌ๋Ÿผ๋ช…: name)๊ฐ€ ์ž‘์„ฑํ•œ ๊ธ€์˜ ๊ฐœ์ˆ˜ (์ปฌ๋Ÿผ๋ช…: ContentCount)๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•œ SQL์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
const PART5_2_10 = `
SELECT user.name as name, 
COUNT(content.userId) AS ContentCount
FROM user
LEFT JOIN content ON user.id = content.userId
GROUP BY user.name`;

 

SQL๋ฌธ๋ฒ•์„ ์–ด๋ ต๊ฒŒ ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ๋ง‰์ƒ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋‹ˆ ๊ด€๊ณ„๋ฅผ ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ฌธ๋ฒ•์€ ํฌ๊ฒŒ ์–ด๋ ต์ง€ ์•Š๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

 

 

'TIL -์ผ๊ฐ„ํ•™์Šต๊ธฐ๋ก > ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

NOSQL - Mongo DB  (0) 2022.03.15

๋Œ“๊ธ€