사용자 활동에 대한 코호트 분석 보고서의 SQL 버전으로, Data Explorer 플러그인 내에서 사용됩니다.
이 보고서는 Discourse Solved 플러그인이 활성화되어 있어야 합니다.
이 코호트 분석 보고서는 특정 시작 날짜 이후에 가입한 사용자의 활동을 추적하여 사용자 참여도에 대한 통찰력을 제공합니다. 특히, 가입 후 매월 게시글 작성 및 해결책 제공이 특정 임계값을 충족하거나 초과하는 사용자에 초점을 맞춥니다.
이 보고서는 커뮤니티 관리자가 게시글 작성 및 주제에 대한 해결책 제공과 관련하여 새로운 사용자를 장기적으로 유지하고 참여시키는 커뮤니티의 효과를 이해하는 데 유용합니다. 또한 커뮤니티 건전성을 평가하고 커뮤니티 성장 전략의 효과를 식별하는 데에도 도움이 될 수 있습니다.
가입 후 월별 활성 사용자 수 (최소 게시글 + 해결책 매개변수)
--[params]
-- date :start_date = 2023-01-01
-- int :min_posts_per_month = 1
-- int :min_solutions_per_month = 1
WITH user_cohorts AS (
SELECT
id AS user_id,
DATE_TRUNC('month', created_at) AS cohort,
COUNT(id) OVER (PARTITION BY DATE_TRUNC('month', created_at)) AS users_signed_up
FROM users
WHERE created_at >= :start_date
),
posts_activity AS (
SELECT
p.user_id,
EXTRACT(YEAR FROM AGE(p.created_at, u.created_at)) * 12 + EXTRACT(MONTH FROM AGE(p.created_at, u.created_at)) AS months_after_registration,
DATE_TRUNC('month', u.created_at) AS cohort
FROM posts p
JOIN users u ON p.user_id = u.id
WHERE p.created_at >= u.created_at
),
solutions_counts AS (
SELECT
p.user_id,
COUNT(p.user_id) as solutions_count,
EXTRACT(YEAR FROM AGE(p.created_at, u.created_at)) * 12 + EXTRACT(MONTH FROM AGE(p.created_at, u.created_at)) AS months_after_registration,
DATE_TRUNC('month', u.created_at) AS cohort
FROM discourse_solved_solved_topics dsst
INNER JOIN posts p ON p.id = dsst.answer_post_id
JOIN topics t ON t.id = p.topic_id
JOIN users u ON p.user_id = u.id
WHERE p.created_at >= u.created_at
GROUP BY months_after_registration, cohort, p.user_id
HAVING COUNT(p.user_id) >= :min_solutions_per_month
),
activity_counts AS (
SELECT
cohort,
months_after_registration,
COUNT(user_id) AS posts_count,
user_id
FROM posts_activity
GROUP BY cohort, months_after_registration, user_id
HAVING COUNT(user_id) >= :min_posts_per_month
),
active_users AS (
SELECT
sc.cohort,
sc.months_after_registration,
COUNT(DISTINCT ac.user_id) AS active_users
FROM solutions_counts sc
FULL JOIN activity_counts ac ON sc.user_id = ac.user_id
AND sc.months_after_registration = ac.months_after_registration
AND sc.cohort = ac.cohort
GROUP BY sc.cohort, sc.months_after_registration
),
cohorts_series AS (
SELECT generate_series AS months_after_registration
FROM generate_series(0, 11)
),
cohorts AS (
SELECT
cohort,
MAX(users_signed_up) AS users_signed_up
FROM user_cohorts
GROUP BY cohort
),
cross_join AS (
SELECT
c.cohort,
c.users_signed_up,
cs.months_after_registration
FROM cohorts c
CROSS JOIN cohorts_series cs
),
final_counts AS (
SELECT
cj.cohort,
cj.users_signed_up,
cj.months_after_registration,
COALESCE(au.active_users, 0) AS active_users
FROM cross_join cj
LEFT JOIN active_users au ON au.cohort = cj.cohort AND au.months_after_registration = cj.months_after_registration
)
SELECT
TO_CHAR(cohort, 'Mon YYYY') AS "Joined In", -- Include the year in the Joined In column
users_signed_up AS "Users Signed Up",
MAX(CASE WHEN months_after_registration = 0 THEN active_users END) AS "Month 1",
MAX(CASE WHEN months_after_registration = 1 THEN active_users END) AS "Month 2",
MAX(CASE WHEN months_after_registration = 2 THEN active_users END) AS "Month 3",
MAX(CASE WHEN months_after_registration = 3 THEN active_users END) AS "Month 4",
MAX(CASE WHEN months_after_registration = 4 THEN active_users END) AS "Month 5",
MAX(CASE WHEN months_after_registration = 5 THEN active_users END) AS "Month 6",
MAX(CASE WHEN months_after_registration = 6 THEN active_users END) AS "Month 7",
MAX(CASE WHEN months_after_registration = 7 THEN active_users END) AS "Month 8",
MAX(CASE WHEN months_after_registration = 8 THEN active_users END) AS "Month 9",
MAX(CASE WHEN months_after_registration = 9 THEN active_users END) AS "Month 10",
MAX(CASE WHEN months_after_registration = 10 THEN active_users END) AS "Month 11",
MAX(CASE WHEN months_after_registration = 11 THEN active_users END) AS "Month 12"
FROM final_counts
GROUP BY cohort, users_signed_up
ORDER BY cohort
SQL 쿼리 설명
매개변수
이 보고서는 세 가지 매개변수를 사용합니다:
start_date: 새로운 사용자 가입 추적을 시작할 날짜.min_posts_per_month: 사용자가 활성으로 간주되려면 한 달 동안 작성해야 하는 최소 게시글 수.min_solutions_per_month: 사용자가 활성으로 간주되려면 한 달 동안 제공해야 하는 최소 해결책(수락된 답변) 수.
사용자가 해당 달에 활성으로 간주되려면 min_posts_per_month과 min_solutions_per_month 요구 사항을 모두 충족해야 합니다.
CTE (공통 테이블 표현식)
제공된 SQL 쿼리는 최소 게시글 및 해결책 기준에 따라 가입 후 월별 활성 사용자를 계산하는 과정을 세분화하기 위해 여러 공통 테이블 표현식(CTE)을 사용합니다. 각 CTE에 대한 설명은 다음과 같습니다:
user_cohorts
이 CTE는 가입 월을 기준으로 사용자 코호트를 식별합니다. 각 사용자의 경우, 가입 월(cohort)을 계산하고 같은 달에 가입한 사용자의 총 수를 집계합니다. 이는 각 코호트의 초기 규모를 이해하는 데 도움이 됩니다.
posts_activity
이 CTE는 가입 후 사용자의 게시글 작성 활동을 추적합니다. 각 게시글에 대해 사용자 등록일 이후 몇 달이 지났는지(months_after_registration)를 계산하고, 사용자의 가입 코호트별로 그룹화합니다. 이는 사용자가 시간 경과에 따라 콘텐츠를 게시하는 활동 수준을 추적하는 데 사용됩니다.
solutions_counts
이 CTE는 사용자가 제공한 해결책(수락된 답변)을 집계하는 데 초점을 맞춥니다. 해결책으로 표시된 게시글을 필터링하여 각 사용자별로 집계하며, 사용자가 가입한 후에만 작성된 게시글이 고려되도록 합니다. 또한 각 해결책에 대해 사용자의 가입일 이후 몇 달이 지났는지도 계산합니다. 사용자는 지정된 월별 최소 해결책 수를 충족하거나 초과하는 경우에만 이 집계에 포함됩니다.
activity_counts
이 CTE는 등록 후 월별 각 사용자의 게시글 수를 집계합니다. 사용자를 가입 코호트와 등록 후 경과 월별로 그룹화한 후, 작성된 게시글 수를 집계합니다. 지정된 월별 최소 게시글 수를 충족하거나 초과하는 사용자만 이 집계에 포함됩니다.
active_users
이 CTE는 solutions_counts와 activity_counts의 데이터를 결합하여 활성 사용자를 식별합니다. 활성 사용자는 게시글 및 해결책 기준을 모두 충족하는 사용자를 의미합니다. 게시글과 해결책에 대해 설정된 기준에 따라 활성인 고유한 사용자를 가입 코호트와 등록 후 경과 월별로 그룹화하여 집계합니다.
cohorts_series
이 CTE는 등록 후 월 수를 나타내는 0부터 11까지의 숫자 시퀀스를 생성합니다. 이는 활성 사용자가 없는 월이 있더라도 최종 보고서에 최대 12개월까지의 데이터가 포함되도록 보장하기 위해 사용됩니다.
cohorts
이 CTE는 user_cohorts의 데이터를 집계하여 각 코호트에 가입한 사용자의 총 수를 가져옵니다. 이는 최종 보고서에 각 코호트의 총 가입 사용자 수가 포함되도록 보장합니다.
cross_join
이 CTE는 cohorts CTE와 cohorts_series CTE 간의 교차 조인(cross join)을 수행합니다. 이를 통해 가입 후 각 월에 대해 모든 코호트가 표현되도록 하여, 최종 단계에서 각 월별 활성 사용자를 계산하는 것을 용이하게 합니다.
final_counts
이 CTE는 이전의 모든 CTE를 결합하여 각 코호트별로 가입 후 월별 최종 활성 사용자 수를 계산합니다. active_users CTE의 활성 사용자를 cross_join CTE에서 생성된 코호트와 월과 일치시키기 위해 왼쪽 조인(LEFT JOIN)을 사용합니다. 활성 사용자가 없는 경우 0으로 기본값을 설정하여 각 코호트-월 쌍에 활성 사용자 수가 포함되도록 보장합니다.
최종 SELECT
쿼리의 최종 SELECT 문은 사용자의 가입 월과 연도를 기준으로 코호트로 그룹화한 후, 가입 후 최대 1년 동안의 월별 활성 사용자 수를 계산합니다. 이는 데이터 변환과 조건부 집계의 조합을 통해 수행되며, 데이터를 각 행이 코호트에 해당하고 각 열이 가입 후 월별 활성 사용자 수를 나타내는 형식(“Month 1”부터 “Month 12”까지)으로 피벗(pivot)합니다.
결과
보고서는 다음 열을 가진 표를 출력합니다:
- Joined In: 코호트의 월과 연도(사용자가 가입한 시점).
- Users Signed Up: 해당 코호트에 가입한 사용자의 총 수.
- Month 1 to Month 12: 가입 후 최대 12개월까지의 월별 활성 사용자 수.
결과 예시
| 가입 월 | 가입 사용자 수 | 1개월 | 2개월 | 3개월 | 4개월 | 5개월 | 6개월 | 7개월 | 8개월 | 9개월 | 10개월 | 11개월 | 12개월 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2023년 1월 | 50 | 40 | 8 | 4 | 3 | 3 | 3 | 4 | 3 | 2 | 1 | 1 | 4 |
| 2023년 2월 | 63 | 40 | 7 | 5 | 3 | 2 | 2 | 7 | 2 | 2 | 2 | 1 | 1 |
| … | … | … | … | … | … | … | … | … | … | … | … | … | … |
보고서의 전체 결과는 start_date 이후 1년 치 데이터를 출력합니다.