내일배움캠프/SQL

예제로 익히는 SQL 5회차 정답

hyezdata 2025. 2. 27. 17:47

1. JOIN 활용

SELECT CASE WHEN p.pay_amount IS NULL THEN '결제 안함'
	ELSE '결제함' END AS gb,
	COUNT(DISTINCT u.game_account_id) AS usercnt
FROM users u LEFT JOIN payment p ON u.game_account_id=p.game_account_id
GROUP BY 1

첨에 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 outer join 
	(	select game_account_id 
		from basic.payment
	)as b
on a.game_account_id=b.game_account_id
group by case when b.game_account_id is null then '결제안함' else '결제함' end
;

 

결제한 유저와 결제하지 않은 유저를 조회해야 하므로 INNER JOIN 사용

INNER JOIN을 하게 되면 결제한 유저만 조회됨

2. JOIN 응용1

SELECT a.game_account_id,
	actor_cnt,
	sumamount
FROM(
	SELECT u.game_account_id,
		COUNT(DISTINCT u.game_actor_id) AS actor_cnt,
		SUM(p.pay_amount) AS sumamount
	FROM (SELECT *
		FROM users
		WHERE serverno>=2
		) u
	LEFT JOIN
		(SELECT *
		FROM payment
		WHERE pay_type='CARD'
		) p
	ON u.game_account_id=p.game_account_id
	GROUP BY u.game_account_id
	) a
WHERE a.actor_cnt>=2
ORDER BY sumamount DESC
# 정답 쿼리
select *
from(	select a.game_account_id, count(distinct game_actor_id) as actor_cnt,
      sum(pay_amount)as sumamount 
		from(	select game_account_id, game_actor_id 
				  from basic.users 
				  where serverno>=2
			)as a 
		inner join 
			(	select distinct game_account_id, pay_amount, approved_at
				from basic.payment
				where pay_type='CARD'
			)as b 
		on a.game_account_id=b.game_account_id 
		group by a.game_account_id
	)as a 
where actor_cnt>=2
order by sumamount desc

 

조건1에서 '모두를 만족하는 경우' 라고 했으니까 INNER JOIN 써야 함...!

으이그

 

3. JOIN 응용2

SELECT serverno,
	CONVERT(AVG(diffdate), SIGNED) AS avgdiffdate
FROM(
	SELECT u.game_account_id,
		DATEDIFF(DATE_FORMAT(p.date2, '%Y-%m-%d'), u.first_login_date) AS diffdate,
		u.serverno
	FROM 
		(SELECT game_account_id,
				first_login_date,
				serverno
		FROM users
		) u
	INNER JOIN
		(SELECT game_account_id,
			MAX(approved_at) AS date2
		FROM payment
		GROUP BY game_account_id
		) p
	ON u.game_account_id=p.game_account_id
	WHERE u.first_login_date<p.date2
	) a
WHERE diffdate>=10
GROUP BY a.serverno
ORDER BY a.serverno DESC
# 정답 쿼리 
select serverno, round(avg(diffdate),0)as avgdiffdate
from(	select a.game_account_id, datediff(date_format(date2,('%Y-%m-%d')) ,first_login_date) as diffdate,serverno
			from(	  select game_account_id, first_login_date, serverno
					    from basic.users 
				   )as a
			inner join 
				   (	select game_account_id, max(approved_at)as date2 
					    from basic.payment
					    group by game_account_id
				    )as c 
			on a.game_account_id=c.game_account_id 
			where date2>first_login_date
		)as d 
where diffdate>=10
group by serverno
order by serverno desc

728x90
반응형