저번 SQL 라이브세션 과제는 TIL에 포함했었는데,
이제는 따로 게시글을 분리하고자 한다.
SELECT
serverno
, substr(first_login_date, 1, 7) as 'm'
, count(distinct game_account_id) as 'usercnt'
FROM
USERS
GROUP BY
serverno
, 2
;
처음에는 date_format() 함수를 사용하려 했는데
first_login_date가 문자열(varchar) 형식이더라
왜 날짜 데이터가 아닌지는 모르겠지만, 문자열이라면 substr() 함수가 더 맞는 것 같아서 이쪽으로 선회
SELECT
first_login_date
, count(distinct game_actor_id) as 'actor_cnt'
FROM
USERS
GROUP BY
1
HAVING
count(*) > 10
;
SELECT
serverno
, CASE
WHEN first_login_date < '2024-01-01' THEN '기존유저'
ELSE '신규유저'
END as 'gb'
, count(distinct game_actor_id) as 'cnt_character'
, avg(level) AS 'avg_level'
FROM
USERS
GROUP BY
1
, 2
;
사실 이 문제는 풀이를 듣고 싶은 마음인데,
조건3이 avg(level)으로 바로 해결되는 게 잘 이해가 되지 않는다
GROUP BY를 1, 2로 했으니까 severno와 gb로 한 것인데,
그렇다면 엄밀히 말해서 '서버별 평균레벨'이 아니라 '서버별, 기존/신규유저의 평균레벨'이 맞는 표현 아닐까 싶어서...
'서버별 평균레벨'은 기존, 신규 유저를 전부 합해서 평균을 계산해야 맞지 않을까?
그래서 예시 답안 이미지가 공개되기 전까지 저 식이 아니라고 생각했고,
GROUP BY를 서버로만 해놓은 서브쿼리를 만들어서 조인을 하고, 양쪽에서 하나씩 따서 출력하는 방식으로 해야하는 지 고민하고 있었다...
SELECT
*
FROM
(
SELECT
first_login_date
, count(DISTINCT game_actor_id) AS 'actor_cnt'
FROM
basic.USERS
GROUP BY
FIRST_LOGIN_DATE
) aa
WHERE
aa.actor_cnt > 10
;
처음엔 여기까지만 진행했다
조건 2까지는 수월했는데, 조건 3은 바로 떠오르지 않았기에
SELECT
DISTINCT actor_cnt
FROM(
SELECT
GAME_ACCOUNT_ID
, count(DISTINCT GAME_ACTOR_ID) AS 'actor_cnt'
FROM
basic.USERS
WHERE
LEVEL >= 30
GROUP BY
GAME_ACCOUNT_ID
HAVING
actor_cnt >= 2
) aa
ORDER BY
actor_cnt
;

다시 처음부터 생각해보다가,
서브쿼리만 떼어내서 만져보다가 그 출력 결과를 보고 다시 생각을 해보았다


"그냥 이걸 count하면 되는 거 아닌가?"
SELECT
DISTINCT actor_cnt
, count(actor_cnt) AS 'accnt'
# 서브쿼리에서 group by를 사용했기에 위의 count는 distinct가 필수가 아니다
FROM(
SELECT
GAME_ACCOUNT_ID
, count(DISTINCT GAME_ACTOR_ID) AS 'actor_cnt'
FROM
basic.USERS
WHERE
LEVEL >= 30
GROUP BY
GAME_ACCOUNT_ID
HAVING
actor_cnt >= 2
) aa
GROUP BY
actor_cnt
ORDER BY
actor_cnt
;