์ŠคํŒŒ๋ฅดํƒ€ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„(25.12.01~)

์ŠคํŒŒ๋ฅดํƒ€ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„_๋ณธ์บ ํ”„_data11๊ธฐ ๊น€์„ ์˜_TIL_Day 3

0๏ธโƒฃ 2025. 12. 24. 21:20

<์˜ค๋Š˜์˜ ํ•™์Šต>

  • 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.๊ฐ ๊ตญ๊ฐ€ ๋‚ด์—์„œ ๊ฒฝ์Ÿํ•  ๋•Œ)