Algorithm๐Ÿค/SQL

[SQL 3ํšŒ์ฐจ ์ˆ™์ œ] join ๋ฌธ์ œ

ํŒŒ์นดํŒŒ์˜ค 2024. 4. 28. 01:25

 

# ๋ฌธ์ œ ์„ค๋ช…

 

ํ…Œ์ด๋ธ”์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

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_idCOUNT(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