<์ค๋์ ํ์ต>
- SQL ๋ผ์ด๋ธ ์ธ์ 2ํ์ฐจ
- SQL ๋ผ์ด๋ธ ์ธ์ : ๊ณผ์
- SQL ์ฌ์ ์บ ํ ํ์คํธ ๋๋จธ์ง
<ํ์ต๋ด์ฉ ์ ๋ฆฌ>
1. SQL ๋ผ์ด๋ธ ์ธ์ 2ํ์ฐจ
- limit n : ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ํ ์๋ฅผ ์ ํ
ํญ์ ์ฟผ๋ฆฌ ๋งจ ๋ง์ง๋ง์ ์์น - select, from ๋ฑ ๊ตฌ๋ฌธ์์ ๋ฌธ๋ฒ ์ ์ ๋ ๊ฐ๋ฅํ๋ฉด ์ค ๋๋ ์ ์ ๊ธฐ
- DB ์์ Table์ ๊ฐ์ ธ์ฌ ๋๋ => DB.Table
select logid as id,
device as dv,
country as ct
from basic.game_logs
limit 15;
- ๋ ์ง๊ฐ์ ๋ฌธ์์ด (yyyy-mm-dd) : '-'๋ฅผ ํฌํจํ๊ณ ์๊ธฐ ๋๋ฌธ์
๋จ, ๋ฌธ์์ด ์์ ์ซ์๋ฅผ ํฌํจํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฐ์ฐ ๊ฐ๋ฅ.
sql์์ ์ ํฌ๋งท์ ๋ ์ง๊ฐ์ด๋ผ๊ณ ์๋์ผ๋ก ์ธ์ - where ์ ์ and์ or ๋ชจ๋ ์์ ์, and๊ฐ ๋จผ์ ํด์๋จ.
// ๊ดํธ ์๋ ๋ฒ์
SELECT action_type, country
FROM basic.game_logs
WHERE action_type='login'
OR action_type='purchase'
AND country='KR';
-- action_type='login'
-- action_type='purchase' and country='KR'
-- and๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋ค ์กฐ๊ฑด์ด ์ฐ์ ๊ณ ๋ ค๋จ.
//๊ดํธ ์๋ ๋ฒ์
SELECT action_type, country
FROM basic.game_logs
WHERE (action_type='login'OR action_type='purchase')
AND country='KR';
-- action_type='login' OR action_type='purchase'
-- country='KR'
- IN(์กฐ๊ฑด1, ์กฐ๊ฑด2)
and X / or์ ๊ฐ๋ ์ผ๋ก ์ฌ์ฉ๋จ.
ex. login ์ด๊ฑฐ๋ logout์ธ ํ
SELECT logid, country, device, action_type
FROM basic.game_logs
WHERE country IN ('KR','JP') --'KR'์ด๊ฑฐ๋ 'JP'์ธ ๋ฐ์ดํฐ
LIMIT 10;
- Like '์ฐพ์ ํจํด'
- %: ๊ธ์ 0๊ฐ ์ด์ / ๊ธธ์ด ์ ํ X
- _: ๊ธ์ 1๊ฐ / ์ ํํ ํ ๊ธ์ (๋ค์ฏ ๊ธ์๋ฅผ ์ฐพ์ ๋๋ '_____') - NULL <> 0, ๋น ๋ฌธ์์ด
: ๊ฐ์ด ์์ / ๋ฏธ์
- where ์ ์ "is null / in not null" ํํ๋ก ์ฌ์ฉํจ.
- ๐ก์ ๋ ฌ ์ NULL์ด ์ด๋ป๊ฒ ๋ฐฐ์น๋๋์ง๋ (ex. ์ค๋ฆ์ฐจ์: ๋งจ ์๋ / ๋ด๋ฆผ์ฐจ์: ๋งจ ์), ์ ๋ ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ๊ผญ ํ์ธํ๋ ์ต๊ด์ด ์ข์ต๋๋ค.
**null๊ฐ์ด๋ผ์ ํน์ ์์น๋ก ์ ๋ ฌ๋ ๊ฒ์ ์๋ฏธ ์๋ ๋ฐ์ดํฐ๋ก ์ฐฉ๊ฐํ์ง ์๊ธฐ! - ๋ชจ๋ ์ง๊ณ ํจ์๋ Null ์ ์ธํ๊ณ ๊ณ์ฐ (*Count(*) ์ ์ธ)
- ex. SUM(score) → 100 + 80 + 60 = 240 (NULL ์ ์ธ)
AVG(score) → (100 + 80 + 60) / 3 = 80 (NULL ์ ์ธ, 3๋ช ๊ธฐ์ค)
- Null์ 0์ผ๋ก ์ฒ๋ฆฌ?
AVG(ifnull(score, 0)) → (100 + 80 + 0 + 60) / 4 = 60
IFNULL(์ปฌ๋ผ๋ช , '๋์ฒดํ ๊ฐ') - order by
- ์ ๋ ฌ๊ธฐ์ค์ผ๋ก ์ค์ ํ๋ ์ปฌ๋ผ์ด ์ฌ๋ฌ ๊ฐ์ผ ๊ฒฝ์ฐ, ์ปฌ๋ผ ๋ชจ๋์ ์ ๋ ฌ๊ธฐ์ค(asc, desc) ์ค์ .
- ์์ ์จ ์ปฌ๋ผ์ ์ ๋ ฌ์์๊ฐ ๊ฐ์ฅ ๋์.
SELECT logid, log_date, game_account_id, level, exp
FROM basic.game_logs
ORDER BY level DESC, exp asc -- level์ ๋ด๋ฆผ์ฐจ์ / ๊ฐ์ level ์์์ exp๊ฐ ์ฌ๋ฆผ์ฐจ์
LIMIT 10;
- SELECT์์ ๋ง๋ ์ปฌ๋ผ ๋ณ์นญ(์: level_group)์ ORDER BY์์๋ ์ธ ์ ์์ง๋ง, WHERE์์๋ ์ธ ์ ์์ต๋๋ค.
์๋๋ฉด WHERE๊ฐ ์คํ๋ ๋๋ ๊ทธ ๋ณ์นญ ์ปฌ๋ผ ๊ฐ์ด ์์ง ํ์ ๋์ง ์์๊ธฐ ๋๋ฌธ์ด์์.
<์ฟผ๋ฆฌ ์คํ ์์>
FROM → ON → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY
2. SQL ๋ผ์ด๋ธ ์ธ์
# ๋ฐ์ผ๋ฆฌ ๊ณผ์
๋ฌธ์ 1)
login ์ด๋ฒคํธ ์ค์์ country = 'KR' ์ธ ๋ฐ์ดํฐ์ logid, log_date, game_account_id, device, referrer ๋ฅผ ์ถ๋ ฅํ๊ณ , logid ์ค๋ฆ์ฐจ์ ์ ๋ ฌํด์ 20๊ฐ๋ง ๋ณด์ฌ์ฃผ์ธ์.
select logid,
log_date,
game_account_id,
device,
referrer
from basic.game_logs
where action_type = 'login' and country='KR'
order by logid asc
limit 20;
๋ฌธ์ 2)
item_gain ์ค item_qty >= 10 ์ธ ๋ก๊ทธ๋ฅผ ์ฐพ๊ณ , logid, log_date, game_account_id, item_name, item_qty ๋ฅผ ์ถ๋ ฅํ์ธ์. ์ ๋ ฌ์ item_qty DESC, log_date DESC ํ ์์ 30๊ฐ๋ฅผ ๋ณด์ฌ์ฃผ์ธ์.
select logid,
log_date,
game_account_id,
item_name,
item_qty
from basic.game_logs
where action_type='item_gain'
and item_qty>=10
order by item_qty desc, log_date desc
limit 30;
๋ฌธ์ 3)
`action_type` ์ `purchase` ์ด๋ฒคํธ ์ค `country IN ('KR', 'JP')` ์ธ ๋ฐ์ดํฐ๋ฅผ ๋์์ผ๋ก ์๋ ์ปฌ๋ผ์ ์ถ๋ ฅํ์ธ์.
- `logid, game_account_id, country, item_name, item_qty`
- `referrer`๊ฐ `NULL`์ด๋ฉด `'unknown'`, ์๋๋ฉด ์๋ `referrer` ๊ฐ์ ์ฐ๋ `referrer_group` ์ปฌ๋ผ์ **CASE WHEN**์ผ๋ก ๋ง๋ค์ด ํจ๊ป ์ถ๋ ฅ
- ์ ๋ ฌ: `log_date DESC`, `logid DESC` / `LIMIT 50`
select logid,
game_account_id,
country, item_name,
item_qty,
case when referrer is null then 'unknown'
else referrer
end as referrer_group
from basic.game_logs
where action_type='purchase'
and country in ('KR', 'JP')
order by log_date DESC, logid DESC
LIMIT 50;
๋ฌธ์ 4)
“ํํฐ ํ๋ ์ด ๋ก๊ทธ”๋ง ๋ฝ๊ณ ์ถ์ต๋๋ค. party_id IS NOT NULL ์ธ ํ ์ค์์, action_type IN ('quest_complete', 'item_gain') ์ธ ๋ฐ์ดํฐ๋ง ์ถ๋ ฅํ์ธ์.
- ์ปฌ๋ผ: logid, log_date, game_account_id, action_type, party_id, party_members
- ์ ๋ ฌ: party_members DESC, logid ASC / LIMIT 30
select logid, log_date, game_account_id, action_type, party_id, party_members
from basic.game_logs
where party_id is not NULL
and action_type in ('quest_complete', 'item_gain')
order by party_members desc, logid asc
LIMIT 30;
# ๋ฐ์ผ๋ฆฌ ํด์ฆ
## Q1. SELECT๊ฐ ์ฃผ๋ก ์ ํํ๋ ๊ฒ์?
A. ํ(row)
B. ์ด(column)
C. ํ
์ด๋ธ
D. DBMS
## Q2 NULL ๋น๊ต๋ก ์ฌ๋ฐ๋ฅธ ๊ฒ์?
A. `col = NULL`
B. `col != NULL`
C. `col IS NULL`
D. `col <> NULL`
## Q3. ๋ค์ ์ค ์ผ๋ฐ์ ์ผ๋ก ์ฐ์ ์์๊ฐ ๋์ ๊ฒ์? (MySQL ๊ธฐ์ค)
A. OR
B. AND
## Q4. `LIKE '_____'` ๋ ๋ฌด์์ ์๋ฏธํ๋์?
A. 5๊ธ์ ๋ฌธ์์ด๊ณผ ๋งค์นญ
B. 5๊ธ์ ์ด์
C. `_` ๋ฌธ์ ํฌํจ
D. ๊ณต๋ฐฑ ํฌํจ
Q5. ๋ณ์นญ(alias) AS๋ก ๋ง๋ ์ปฌ๋ผ์ WHERE์์ ์ฌ์ฉํ ์ ์๋ค (O / X)
3. SQL ์ฌ์ ์บ ํ ํ์คํธ
//21.lol_users ํ
์ด๋ธ์์ ๊ฐ ์ ์ ์ ๋ ์ดํ
(rating) ์์๋ฅผ ๊ณ์ฐํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์! ์ ์ฒด ์ง์ญ(region) ๊ธฐ์ค์ด๊ณ ์์๋ ๋ ์ดํ
์ด ๋์์๋ก ๋์์ผํด์. (e.g. rating 1400 ์ ์ ์ ์์ > rating 1350 ์ ์ ์ ์์)
//๐์ค๋ต
select *
from lol_users
order by region asc, rating desc
//๐กํด์ค
select id,
name,
region,
rating,
rank() over(order by rating desc) as lol_ranking --rank() over(partition by(์ ํ) order by(ํ์))
from lol_users;
//22.lol_users ํ
์ด๋ธ์์ ๊ฐ์ฅ ๋ฆ๊ฒ ๊ฒ์์ ์์ํ(join_date) ์ ์ ์ ์ด๋ฆ์ ์ ํํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
//์ ๋ต
select name,
join_date
from lol_users
where join_date is not null
order by join_date desc
limit 1;
//23.lol_users ํ
์ด๋ธ์์ ์ง์ญ๋ณ๋ก ๋ ์ดํ
์ด ๋์ ์์ผ๋ก ์ ์ ๋ค์ ์ ๋ ฌํด์ ๋์ดํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
//์ ๋ต
select *
from lol_users
order by region, rating desc;
//24.lol_users ํ
์ด๋ธ์์ ์ง์ญ๋ณ๋ก ํ๊ท ๋ ์ดํ
์ ๊ณ์ฐํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
//์ ๋ต
select region,
avg(rating) as avg_rating
from lol_users
group by region;
//25. lol_feedbacks ํ
์ด๋ธ์์ ๋ง์กฑ๋ ์ ์(satisfaction_score)์ ๋ฐ๋ผ ํผ๋๋ฐฑ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
--์ ๋ต
select id, user_name, satisfaction_score, feedback_date
from lol_feedbacks
order by satisfaction_score desc;
//26.lol_feedbacks ํ
์ด๋ธ์์ ๊ฐ ์ ์ ๋ณ๋ก ์ต์ ํผ๋๋ฐฑ์ ์ฐพ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
--์ ๋ต
select user_name,
max(feedback_date) as latest_feedback_date
from lol_feedbacks
group by user_name;
//27.lol_feedbacks ํ
์ด๋ธ์์ ๋ง์กฑ๋ ์ ์๊ฐ 5์ ์ธ ํผ๋๋ฐฑ์ ์๋ฅผ ๊ณ์ฐํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
--์ ๋ต
select count(*) as feedback_cnt
from lol_feedbacks
where satisfaction_score=5;
//28.lol_feedbacks ํ
์ด๋ธ์์ ๊ฐ์ฅ ๋ง์ ํผ๋๋ฐฑ์ ๋จ๊ธด ์์ 3๋ช
์ ๊ณ ๊ฐ์ ์ฐพ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
--๐์ค๋ต
select user_name,
count(user_name) as cnt_fb
from lol_feedbacks
order by count(user_name) desc
limit 3;
--๐กํด์ค
select user_name,
count(user_name) as cnt_fb
from lol_feedbacks
group by user_name --๋ถ๋ฅ ๊ธฐ์ค ๊ผญ ์ ๊ธฐ
order by count(user_name) desc --order by cnt_fb๊ณผ ๊ฐ์ด ๋ณ์นญ ์ฌ์ฉ ๊ฐ๋ฅ
--order by๊ฐ select ๋ณด๋ค ๋ค์ ์คํ๋๊ธฐ ๋๋ฌธ์ select์ ๋ณ์นญ์ ๋ถ๋ฌ์ฌ ์ ์์.
limit 3;
//29.lol_feedbacks ํ
์ด๋ธ์์ ํ๊ท ๋ง์กฑ๋ ์ ์๊ฐ ๊ฐ์ฅ ๋์ ๋ ์ง๋ฅผ ์ฐพ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ์ธ์!
--์ ๋ต
select feedback_date,
avg(satisfaction_score) as avg_scor
from lol_feedbacks
group by feedback_date
order by avg_score desc
limit 1;
<์ค๋ต๋ ธํธ>
21. ๋ญํน ์ง๊ณ ํจ์
rank() over(partition by ์์๋ฅผ ๋๋ ์ ๋งค๊ธธ ๊ธฐ์ค(์ ํ) order by ์์ ๊ธฐ์ค(ํ์))
- ๋์ ํ์ฉ / ๊ฐ์ ์์๋ก ํ๋จ
- partition by : ํด๋น ๊ธฐ์ค๋ง๋ค ์์ ๋ฆฌ์ (ex.๊ฐ ๊ตญ๊ฐ ๋ด์์ ๊ฒฝ์ํ ๋)
'์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ(25.12.01~)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| SQL ๊ฑท๊ธฐ๋ฐ ๋ฌธ์ ํตํฉ (1) | 2025.12.27 |
|---|---|
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 4 (1) | 2025.12.26 |
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 2 (0) | 2025.12.23 |
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 1 (1) | 2025.12.22 |
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_์ฌ์ ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_251218 (1) | 2025.12.18 |