[SQL 3ํ์ฐจ ์์ ] join ๋ฌธ์
# ๋ฌธ์ ์ค๋ช
ํ ์ด๋ธ์ ๋ค์๊ณผ ๊ฐ๋ค
users ํ ์ด๋ธ - ํ์ ์ ์ ํ ์ด๋ธ
payment ํ ์ด๋ธ - ํ์ ๊ฒฐ์ ํ ์ด๋ธ
< ๋ฌธ์ 1 >
case when ๊ตฌ๋ฌธ๊ณผ join ํจ์๋ฅผ ์ฌ์ฉํ์ฌ, users ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก, ๊ฒฐ์ ๋ฅผ ํ ์ ์ ์ ๊ฒฐ์ ๋ฅผ ํ์ง ์์ ์ ์ ๋ฅผ ์ถ์ถํด์ฃผ์ธ์.๊ฒฐ๊ณผ๊ฐ์ ์๋์ ๊ฐ์์ผ ํฉ๋๋ค.
< ํต์ฌ ๊ฐ๋ >
1. count ์ sum์ ์ฐจ์ด์
count์ sum์ ํท๊ฐ๋ฆฌ์ง ๋ง์!!
# count
ํ ์ด๋ธ์ ํ์ ์
- count(*)
null๊ฐ๊น์ง ํฌํจํด์ ๊ฐ์๋ฅผ ์ผ๋ค
- count(์ปฌ๋ผ)
null๊ฐ์ ์ ์ธํ๊ณ ๊ฐ์๋ฅผ ์ผ๋ค
# sum
ํ ์ด๋ธ์ ์ด ํฉ๊ณ
sum(์ปฌ๋ผ), avg(์ปฌ๋ผ), min(์ปฌ๋ผ), max(์ปฌ๋ผ) ํ์์ผ๋ก ์จ์ผ ํ๋ค
์ด๋ค ์ปฌ๋ผ์ ๋ํด์ ๊ณ์ฐ์ ์ํํ ๊ฒ์ธ๊ฐ๋ฅผ ์ง์ ํด์ผ ํ๋ค
โป count(์ปฌ๋ผ), sum(์ปฌ๋ผ)์์์ ์ปฌ๋ผ์ group by ์ปฌ๋ผ์ด ์๋๋ค
๊ทธ๋ฃน๋ณ๋ก ์ง๊ณํ ์ปฌ๋ผ์ ์ง์ ํ ๋๋ ๋ฐ๋์ group by ๋ถ๋ถ์๋ค๊ฐ ์ฌ์ฉํด์ผ ํ๋ค
2. ์กฐ์ธ๋ฌธ์์
from
left join์ ํ ๋
์๋ธ์ฟผ๋ฆฌ๋ก ์ํ๋ ์ปฌ๋ผ๋ง ๊ฐ์ ธ์จ๋ค๋ฉด ๋ ํจ์จ์ ์ธ ์ฟผ๋ฆฌ๋ฌธ์ด ๋ ์ ์๋ค
[ ์ ์ฒด ]
from users as u
left join payment as p
on u.game_account_id = p.game_account_id
[ ํ์ํ ๊ฒ๋ง ]
from( select game_account_id
from basic.users
)as a
left join
( select game_account_id
from basic.payment
)as b
on a.game_account_id=b.game_account_id
3. ์ต๊ด์ ์ผ๋ก group by๋ฅผ ์ฐ๋ ๊ฒ์ด ์๋๋ผ group by๋ฅผ ์ ์จ์ผํ๋์ง ์๊ฐํด๋ณด๊ธฐ
group by๋ ๊ฐ์ ๊ฐ์ ํ๋์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์
์ง๊ณ ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ฐ๋ ๊ฒ์ด๋ค
4. GROUP BY๋ฅผ ์ฌ์ฉํ ๋ ์ผ๋ฐ์ ์ผ๋ก SELECT์ ์ ์ง๊ณํจ์๋ฅผ ์ ์ธํ ๋ชจ๋ ์ปฌ๋ผ์ GROUP BY์ ๋ช ์ํด์ฃผ์ด์ผ ํฉ๋๋ค
ex) ๋ฐ๋ฅธ ์์
SELECT id, insta_id, COUNT(price)
FROM a
GROUP BY id, insta_id
ex) ํ๋ฆฐ ์์ --> ์ด๋ ๊ฒ ๋ง์๋๋ก ์ฐ์๋ฉด ์ํ๋ ๊ฐ๊ณผ ๋ค๋ฅธ ๊ฐ์ด ๋์ต๋๋ค.
SELECT id, insta_id, COUNT(price)
FROM a
GROUP BY id
ex) ํ๋ฆฐ ์์ --> ์ด๋ ๊ฒ ๋ง์๋๋ก ์ฐ์๋ฉด ์ํ๋ ๊ฐ๊ณผ ๋ค๋ฅธ ๊ฐ์ด ๋์ต๋๋ค.
SELECT id, COUNT(price), insta_id
FROM a
GROUP BY id
5. users ํ ์ด๋ธ ๋ด์์ ํ์ ์๋ฅผ ์ง๊ณํ ๋ ์ค๋ณต๋ ๋ฐ์ดํฐ ๊ฐ์ด ์์ ์ ์์ผ๋ฏ๋ก
distinct๋ฅผ ์ฌ์ฉํ์๋ค
# ์ ๋ต ์ฝ๋
select case when b.game_account_id is null then '๊ฒฐ์ ์ํจ'
else '๊ฒฐ์ ํจ' end as gb,
count(distinct a.game_account_id)as usercnt
from( select game_account_id
from basic.users
)as a
left join
( select game_account_id
from basic.payment
)as b
on a.game_account_id=b.game_account_id
group by 1
< ๋ฌธ์ 2 >
- ์๋ฒ๋ฒํธ๊ฐ 2 ์ด์์ธ ๋ฐ์ดํฐ์ ๊ฒฐ์ ๋ฐฉ์์ด CARD ์ธ ๊ฒฝ์ฐ๋ฅผ joinํด ์ฃผ์๊ณ
- game_account_id ๋ฅผ ๊ธฐ์ค์ผ๋ก game_actor_id ๊ฐฏ์๋ฅผ ์ค๋ณต๊ฐ์์ด ์ธ์ด์ฃผ์๊ณ , actorcnt ์ผ๋ก ์ปฌ๋ผ๋ช
์ ๋ช
์ํด์ฃผ์ธ์.
- pay_amount ๊ฐ์ ๋ํด์ฃผ์๊ณ , sumamount ์ผ๋ก ์ปฌ๋ผ๋ช
์ ๋ช
์ํด์ฃผ์ธ์.
- having ์ ์ฌ์ฉํ์ง ์๊ณ , subquery ์ฌ์ฉ์ผ๋ก game_actor_id ๊ฐฏ์๊ฐ 2 ์ด์์ธ ๊ฒฝ์ฐ๋ง ์ถ์ถํด์ฃผ์ธ์.
๊ฒฐ๊ณผ๊ฐ์ ์๋์ ๊ฐ์์ผ ํฉ๋๋ค
# ํต์ฌ ๊ฐ๋
1. from ( ์๋ธ์ฟผ๋ฆฌ ) as ๋ณ์นญ์
a,b,c .. ์ด๋ ๊ฒ ๊ฐ๋จํ๊ฒ ์จ์ค ์ฃผ ์๋ค
๊ตณ์ด ๋ชจ๋ ์ปฌ๋ผ์
a.์ปฌ๋ผ, b.์ปฌ๋ผ ์ด๋ฐ์์ผ๋ก ์ธ ํ์๋ ์๊ณ
์ค๋ณต๋๋ ์ปฌ๋ผ์ ํํด์๋ง ์จ์ค๋ ์ถฉ๋ถํ๋ค
2. ์ค์ํ ์๋ธ์ฟผ๋ฆฌ๋ฌธ์
1) where ์ปฌ๋ผ in (์๋ธ์ฟผ๋ฆฌ)
2) from ( ์๋ธ์ฟผ๋ฆฌ ) as ๋ณ์นญ
์ด ์๋ ๊ฒ์ ๊ธฐ์ตํ์
# ์ ๋ต ์ฝ๋
select *
from
(
select a.game_account_id,
count(distinct game_actor_id) as actorcnt,
sum(pay_amount) as sumamount
from ( select game_account_id, game_actor_id
from users
where serverno >= 2
) as a
inner join
( select game_account_id, pay_amount
from payment
where pay_type = 'CARD'
) as b
on a.game_account_id = b.game_account_id
group by a.game_account_id
) a
where actorcnt >= 2
< ๋ฌธ์ 3 >
- user ํ
์ด๋ธ์์ game_account_id, date, serverno ๋ฅผ ์ถ์ถํ ๋ฐ์ดํฐ์ ๋งค์ถ ํ
์ด๋ธ์์ game_account_id ๋ณ ๊ฐ์ฅ ๋ง์ง๋ง ๊ฒฐ์ ์ผ์๋ฅผ ์ฐพ๊ณ join ์ ์งํํด์ฃผ์ธ์.
- ๊ทธ ๋ค์, datediff ํจ์๋ฅผ ์ฌ์ฉํด ๊ฒฐ์ ์ผ์-์ ์์ผ์๋ฅผ ๊ตฌํด์ฃผ์ธ์. ๊ทธ๋ฆฌ๊ณ ์ปฌ๋ผ์ด๋ฆ์ *diffdate๋ก ์ค์ ํด์ฃผ์ธ์.* ๋ ๋ ์ง์ ํ์์ ๊ฐ์์ผ ํฉ๋๋ค.
- ๋ง์ง๋ง์ผ๋ก, ์ธ๋ผ์ธ ๋ทฐ subquery ๋ฅผ ์ด์ฉํ์ฌ ์๋ฒ๋ณ ํ๊ท diffdate๋ฅผ ๊ตฌํด์ฃผ์ธ์.
๋ค๋ง, ํ๊ท datediff ์ปฌ๋ผ์ ์ ์ ํํ๋ก ์ถ๋ ฅ๋์ด์ผ ํฉ๋๋ค. ๋ํ, ์กฐ๊ฑด์ ์ diffdate ๊ฐ์ด 10์ผ ์ด์์ธ ๊ฒฝ์ฐ๋ฅผ ํํฐ๋งํด์ฃผ์ธ์. ๊ทธ๋ฆฌ๊ณ ์๋ฒ๋ฒํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํด์ฃผ์ธ์. (์ ์ฒด๊ฒฐ๊ณผ ์ค ์ผ๋ถ์
๋๋ค.)
# ํต์ฌ ๊ฐ๋
1. ` ` ์ปฌ๋ผ๋ช ์ด date์ ๊ฐ์๋ ๋ฐฑํฑ ์ ๋ถ์ด๊ธฐ
2. ๋ฌธ์ ์๊ตฌ์ฌํญ ์ ๋ฐ๋ฅด๊ธฐ
# ์ ๋ต ์ฝ๋
select serverno,
round(avg(diffdate)) as avgdiffdate
from
(
select a.game_account_id,
datediff(date_format(date2, '%Y-%m-%d'), `date`) as diffdate,
serverno
from ( select game_account_id, `date`, serverno
from users
) as a
inner join
( select game_account_id, max(approved_at) as date2
from payment
group by game_account_id
) as b
on a.game_account_id = b.game_account_id
) as a
where diffdate >= 10
group by serverno
order by serverno desc