[TIL]_2025.02.27 본캠프 11일차 (2): 예제로 익히는 SQL 4,5일차 + 숙제

JIYUU·2025년 2월 28일

🔷 INNER JOIN

  • INNER JOIN의 간단한 예
# INNER JOIN 작성법(기초편)
select 컬럼1, 컬럼2... 
from 테이블명1
inner join 테이블명2   
on a.공통컬럼=b.공통컬럼

테이블 1과 테이블 2의 공통 컬럼이 일치하는 모든 데이터가 조회

  • INNER JOIN과 서브쿼리를 응용한 예

🔷 LEFT JOIN

  • LEFT JOIN의 간단한 예 (WHERE절이 없을 때, 간단하게 조인가능)
  • LEFT를 기준으로 위쪽(왼쪽) 테이블은 '기준 테이블'
  • LEFT를 기준으로 아래쪽(오른쪽) 테이블은 조건에 따라 출력되는 테이블.
    ON절을 만족하지 못할 경우 NULL값으로 출력된다.

🔷 RIGHT JOIN (*잘 사용되지 않음)

  • LEFT JOIN과 정반대로 작동함

🔷 FULL OUTER JOIN
테이블의 모든 데이터를 확인할 때 사용
(MySQL에서는 지원되지 않음)
FULL OUTER JOIN = LEFT JOIN + UNION + RIGHT JOIN으로 사용
비용 이슈 등으로 자주 사용되지는 않음

04. 숙제

문제1 - JOIN 활용
조건1) 알맞은 join 방식을 사용하여 users 테이블을 기준으로, payment 테이블을 조인해주세요.
조건2) case when 구문을 사용하여 결제를 한 유저와 결제를 하지 않은 게임계정을 구분해주시고, 컬럼이름을 gb로 지정해주세요.
조건3) gb를 기준으로 게임계정수를 추출해주세요. 컬럼 이름은 usercnt로 지정해주시고, 결과값은 아래와 같아야 합니다.
힌트: 기준이 되는 테이블의 데이터는 그대로 두어야겠죠?

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

문제2 - JOIN 응용1
조건1) users 테이블에서 서버번호가 2 이상인 데이터와 payment 테이블에서 결제방식이 CARD 모두를 만족하는 경우를 알맞은 방식으로 join 해 주세요. payment 테이블의 매출 금액이 중복되는 것을 방지하기 위해 모든 값을 고유하게 추출해야 합니다.
조건2) 조인한 결과를 바탕으로 users 테이블의 game_account_id 를 기준으로 game_actor_id수를 중복값없이 세고 컬럼 이름을 actor_cnt로 지정해주세요. 또한 pay_amount 값을 더해주시고, 컬럼 이름을 sumamount로 지정해주세요.
조건3) having 을 사용하지 않고, 인라인 뷰 subquery 사용으로 actor_cnt수가 2 이상인 경우만 추출해주세요. 그리고 sumamount를 기준으로 내림차순 정렬해주세요.

문제 3. JOIN 응용2
조건1) user 테이블에서 game_account_id, first_login_date, serverno 를 추출한 결과와
조건2) payment 테이블에서 game_account_id 별 가장 마지막 결제일자를 찾고 그 컬럼이름을 date2로 지정해주세요. 그 다음 inner join 을 진행해주세요. 다만, 첫 접속일자보다 마지막 결제일자가 큰 경우만 추출해주세요.
조건3) 조인 결과를 바탕으로 마지막 결제일자-첫 접속일자 를 구해주세요. 그리고 컬럼이름을 diffdate로 설정해주세요. 두 날짜의 형식은 같아야 합니다.
조건4) 인라인 뷰 subquery 를 이용하여 서버별 평균 diffdate를 구해주시고, 컬럼이름을avgdiffdate로 설정해주세요. 해당컬럼은 정수 형태로 출력되어야 합니다.
조건5) 조건절에 diffdate 값이 10일 이상인 경우를 필터링해주세요. 그리고 서버번호를 기준으로 내림차순 정렬해주세요. 결과값은 아래와 같아야 합니다. 전체결과 중 일부입니다.
힌트) 소수점을 반올림해주는 round 함수를 활용해주세요!

SELECT
	u.game_account_id,
	u.first_login_date,
	u.serverno,
	datediff(str_to_date(sub.date2, '%Y-%m-%d'), str_to_date(u.first_login_date, '%Y-%m-%d')) AS diffdate
FROM
	users u
JOIN (
		SELECT
			game_account_id,
			MAX(approved_at) AS date2
			-- 가장 마지막 결제일자
		FROM
			payment
		GROUP BY
			game_account_id
	) AS sub
ON
	u.game_account_id = sub.game_account_id
WHERE
	sub.date2 > u.first_login_date

0개의 댓글