[MySQL] 실습 내용 [GROUP BY]
2023. 1. 12. 16:18
GROUP BY
- SELECT 시 레코드를 있는 그대로 읽어오는 것이 아니라, 특정 FIELD를 기준으로 같은 값을 갖는 값들을 GROUPING
- 즉, 테이블의 레코드를 그룹핑하여 그룹별로 다양한 정보를 계산
- 먼저 그룹핑을 할 필드를 결정 (하나 이상의 필드가 될 수 있음)
- GROUP BY로 지정 (필드 이름을 사용하거나 필드 일련번호를 사용)
- 다음 그룹별로 계산할 내용을 결정
- 여기서 Aggregate 함수를 사용
- COUNT, SUM, AVG, MIN, MAX, GROUP_CONCAT ...
- 보통 필드 이름을 지정하는 것이 일반적 (alias)
월별 세션 수를 계산하는 SQL
SELECT
LECT(created, 7) AS mon, -- 연도, 월
COUNT(1) AS session_count
FROM prod.session
GROUP BY 1 -- GROUP BY MON, SELECT에서 첫 번째 FIELD를 의미.
-- GROUP BY LEFT(created 7)
ORDER BY 1 -- SELECT 첫 FIELD 기준으로 ORDER
-- 과거 -> 현재
가장 많이 사용된 채널은 무엇인가 ?
-- 사용자 기반?
-- 세션 기반?
두 가지의 경우 생김
- 필요한 정보 - 채널 정보, 사용자 정보 혹은 세션 정보
- 먼저 어느 테이블을 사용해야하나?
- session? 필요 !
- channel?
- 조인 할 필요 X
-- 세선 중심 --
SELECT
channel_id,
COUNT(1) AS session_count,
COUNT(DISTINCT user_id) AS user_count
FROM prod.session
GROUP BY 1 -- GROUP BY channel_id
ORDER BY 2 DESC -- ORDER BY session_count DESC
-- 사용자 중심 --
SELECT
channel_id,
COUNT(1) AS session_count,
COUNT(DISTINCT user_id) AS user_count
FROM prod.session
GROUP BY 1 -- GROUP BY channel_id
ORDER BY 3 DESC -- ORDER BY user_count DESC
가장 많은 세션을 만들어낸 사용자 ID는 무엇인가 ?
SELECT
user_id,
COUNT(1) AS count
FROM prod.session
GROUP BY 1 -- GROUP BY user_id
ORDER BY 2 DESC -- ORDER BY count DESC
LIMIT 1;
월별 유니크한 사용자 수 (MAU - Monthly Active User)
- 한 사용자는 한 번만 카운트 되어야 함.
-- 필요한 정보 : 시간 정보, 사용자 정보
SELECT
LEFT(created, 7) AS mon,
COUNT(DISTINCT user_id) AS user_count
FROM prod.session
GROUP BY 1 -- GROUP BY mon, GROUP BY LEFT(created, 7)
ORDER BY 1;
월별 채널별 유니크한 사용자 수
-- 필요한 정보 : 시간 정보, 사용자 정보, 채널 정보
-- 먼저 어느 테이블을 사용해야하늕 ㅣ생각
-- 이번에는 channel_id가 아닌 channel 이름으로 계산해보자
-- session, channel의 조인 필요
SELECT s.id, s.user_id, s.channel_id. c.channel
FROM session s -- session table에 alias를 줌.
JOIN channel c ON c.id = s.channel_id;
-- 두 개가 같은 경우 레코드를 merge함. 두 table 간의 병합 조건을 제시한 것.
-- channel은 c, session은 s로 지창하면 됨.
-- Alias 먼저 이해 (s,c)
-- JOIN이란 결국 서로 다른 테이블에 존재하는 레코드들은 특정 조건을 바탕으로 병합하는 작업
** 정답 **
SELECT
LEFT(s.created, 7) AS mon,
c.channel,
COUNT(DISTINCT user_id) AS mau
FROM session s
JOIN channel c ON c.id = s.channel_id
GROUP BY 1, 2
ORDER BY 1 DESC, 2;
-- 필드/테이블 이름에 Alias 사용. AS는 필수가 아님.
-- COUNT(DISTINCT s.user_id) AS mau와
-- COUNT(DISTINCT s.user_id) mau는 동일
-- ORDER BY와 GROUP BY:
-- 포지션 번호 VS 필드 이름
-- GROUP BY 1 == GROUP BY month == GROUP BY LEFT(s.created, 7)
'Programming > MySQL' 카테고리의 다른 글
[MySQL] InsertUpdateDelete 2 (0) | 2023.01.12 |
---|---|
[MySQL] InsertUpdateDelete 1 (0) | 2023.01.12 |
[MySQL] 실습 내용 [STRING, ORDER BY, DATE, TYPE CASTING] (0) | 2023.01.12 |
[MySQL] MySQLWorkbench 실습 환경 구축 및 실습 내용 (0) | 2023.01.12 |
[MySQL] WHERE, GROUP BY, ORDER BY 기초 문법 (0) | 2023.01.12 |