[MySQL] 실습 내용 [GROUP BY]

2023. 1. 12. 16:18

GROUP BY

  • SELECT 시 레코드를 있는 그대로 읽어오는 것이 아니라, 특정 FIELD를 기준으로 같은 값을 갖는 값들을 GROUPING
  • 즉, 테이블의 레코드를 그룹핑하여 그룹별로 다양한 정보를 계산

 

  1. 먼저 그룹핑을 할 필드를 결정 (하나 이상의 필드가 될 수 있음)
    1. GROUP BY로 지정 (필드 이름을 사용하거나 필드 일련번호를 사용)
  2. 다음 그룹별로 계산할 내용을 결정
    1. 여기서 Aggregate 함수를 사용
    2. COUNT, SUM, AVG, MIN, MAX, GROUP_CONCAT ...
      1. 보통 필드 이름을 지정하는 것이 일반적 (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)

BELATED ARTICLES

more