Học SQL Qua Challenges

Học SQL Qua Business Case – Onboarding Completion Rate → Vanity Metric (4 Modules)

Bối Cảnh Sản Phẩm

  • Sản phẩm: một app chia hoá đơn nhóm (group bill-splitting — nhiều người cùng chia một khoản chi chung).
  • Business model: freemium (bản cơ bản miễn phí, doanh thu đến từ bản Pro trả phí và quảng cáo).
  • Cách tăng trưởng: organic (tự nhiên — user mới đến do tự tìm hoặc được giới thiệu, không do quảng cáo trả tiền).
  • Động cơ tăng trưởng: network effect (hiệu ứng mạng lưới — một user hiểu app sẽ tạo nhóm và mời thêm người, kéo user mới vào).
Vấn đề cần giải quyết
  • Onboarding (quy trình làm quen sản phẩm cho user mới) hiện được đo bằng completion rate (tỷ lệ hoàn thành — phần trăm user đi hết 6 bước hướng dẫn).
  • Đội sản phẩm dự kiến chi ngân sách để kéo completion rate lên cao hơn.
  • Bạn cần chứng minh completion rate là vanity metric (chỉ số phù phiếm — nhìn đẹp nhưng không phản ánh giá trị thật) và thay completion rate bằng một North Star (chỉ số dẫn đường — phản ánh giá trị cốt lõi của sản phẩm).

Module 1 — Bẫy Completion Rate

Tình Huống
  • Báo cáo hiện tại: completion rate (tỷ lệ user hoàn thành đủ 6 bước hướng dẫn) đạt 62%.
  • Con số 62% đang được diễn giải là dấu hiệu onboarding (quy trình làm quen sản phẩm) tốt.
  • Đề xuất từ đội sản phẩm: chi ngân sách quý sau để kéo completion rate từ 62% lên 75%.
  • Câu hỏi cần trả lời trước khi duyệt ngân sách: completion rate có correlation (tương quan — hai chỉ số cùng tăng hoặc cùng giảm) với day-2 retention (tỷ lệ user quay lại vào ngày thứ 2) hay không.
  • Nếu không có correlation thì việc chi tiền để tăng completion rate không giúp tăng lượng user quay lại.
Minh Hoạ
  • An — hiểu nhanh, không hoàn thành tour:
    • Màn hình đầu hiện sẵn một ví dụ chia hoá đơn mẫu (một khoản chi, kèm phần mỗi người phải trả).
    • An nắm được công dụng app ngay từ ví dụ này.
    • An tạo một khoản chi thật trong phiên đầu tiên.
    • An bấm Skip (bỏ qua) tour ngay sau bước 1, dừng ở max_step = 1.
    • Ngày hôm sau An tự mở lại app.
  • Chi — hoàn thành tour, không hiểu app:
    • Chi bấm Next (tiếp theo) qua đủ 6 bước tour: welcome → tính năng → cách hoạt động → xin quyền → mời bạn → xong.
    • Chi dừng ở max_step = 6, được ghi nhận là completed (đã hoàn thành).
    • Chi không tạo khoản chi nào trong phiên đầu.
    • Ngày hôm sau Chi không mở lại app.
  • Kết luận
    • Chi hoàn thành onboarding còn An thì không.
    • User quay lại là An, không phải Chi.
    • Việc hoàn thành tour không dự đoán được ai sẽ quay lại.
Thuật Ngữ
  • Completion rate (tỷ lệ hoàn thành): phần trăm user đi hết flow onboarding, tức chạm tới bước cuối finish.
  • Day-2 organic return (tỷ lệ quay lại tự nhiên ngày 2): phần trăm user tự mở lại app vào ngày thứ 2.
  • Từ “organic” (tự nhiên) nghĩa là user quay lại do tự muốn, không do notification (thông báo đẩy) hoặc email kéo về.
  • Aha moment (khoảnh khắc “à, ra vậy”): thời điểm user tự hiểu đúng sản phẩm dùng để làm gì.
  • App không có cột dữ liệu nào ghi trực tiếp “user đã hiểu”. Do đó cần dùng proxy (chỉ số thay thế quan sát được) cho aha moment.
  • Proxy được chọn: user tạo khoản chi đầu tiên ngay trong phiên đầu.
Mindset Phân Tích Dữ Liệu
  • Tư duy cốt lõi: một metric (chỉ số) đứng một mình không kết luận được điều gì.
  • Với mỗi metric cần hỏi hai câu: metric này có nối vào goal (mục tiêu) không, và metric này có correlation với kết quả cần đạt không.
  • Vanity metric (chỉ số phù phiếm): chỉ số nhìn đẹp và dễ tăng, nhưng không tương quan với giá trị thật.
  • Cách phát hiện vanity metric: segment (chia user thành các nhóm) rồi so tỷ lệ day-2 return giữa các nhóm.
  • Kỹ thuật cụ thể: dựng bảng chéo 2×2 (bảng hai chiều: completed Y/N × aha Y/N).
    • Với bảng 2×2, so day-2 organic return của từng ô.
    • Nếu completion có tương quan với return thì các ô “completed = Y” phải có return cao rõ rệt.
    • Nếu return của các ô “completed = Y” không cao hơn, completion là vanity metric.
    • Công thức completion rate = finish reached / cohort (số user chạm bước cuối chia tổng cohort — nhóm user cùng vào trong một đợt).
    • Công thức return rate của một nhóm = số user nhóm đó quay lại ngày 2 (organic) / tổng số user nhóm đó.
Phân Tích

Funnel onboarding (đơn vị: user; đọc: mỗi bước là số user chạm tới bước đó):

BướcTên bướcUser chạm tới% còn lại
1welcome1000100%
2feature_overview88088%
3how_it_works76076%
4notification_ask70070%
5invite_friends66066%
6finish62062%

→ Metric: completion rate = 620/1000 = 62%.

Bảng chéo 2×2 (đơn vị: user; return = day-2 organic; công thức return rate = returners/users):

Cách đọc bảng: mỗi user được gắn hai nhãn Y/N, một cho completed và một cho aha, nên rơi vào đúng một trong bốn ô.

  • Ô A = completed Y và aha Y: hoàn thành tour và có tạo khoản chi đầu.
  • Ô B = completed Y và aha N: hoàn thành tour nhưng không tạo khoản chi đầu.
  • Ô C = completed N và aha Y: không hoàn thành tour nhưng có tạo khoản chi đầu.
  • Ô D = completed N và aha N: không hoàn thành tour và không tạo khoản chi đầu.
NhómCompletedAhaUsersReturners (day-2 organic)Return rate
AYY18012670%
BYN4404410%
CNY1207865%
DNN260135%
Tổng100026126.1%

Marginal (chỉ số biên): gộp bảng 2×2 theo một chiều và bỏ qua chiều còn lại, để xem riêng tác động của từng biến.

  • Marginal theo completion = gộp hai ô cùng giá trị completed, không phân biệt aha (A+B so với C+D).
  • Marginal theo aha = gộp hai ô cùng giá trị aha, không phân biệt completed (A+C so với B+D).

Marginals (gộp theo từng chiều):

Cắt theoUsersReturnersReturn rate
Completed = Y (A+B)62017027.4%
Completed = N (C+D)3809123.9%
Aha = Y (A+C)30020468.0%
Aha = N (B+D)700578.1%

Insight (vanity metric lộ diện):

  • So theo chiều completion: completed = Y có return 27.4%, completed = N có return 23.9%.
  • Hai con số 27.4% và 23.9% gần như bằng nhau, chênh lệch nhỏ.
  • So theo chiều aha: aha = Y có return 68.0%, aha = N có return 8.1%.
  • Hai con số 68.0% và 8.1% chênh nhau khoảng 8.4 lần.
  • Kết luận: completion rate không tương quan với return, còn aha thì có tương quan mạnh.
  • Do đó completion rate là vanity metric.

Vì sao marginal của completion đánh lừa (confound — biến gây nhiễu):

  • Confound là một biến ẩn tác động lên kết quả, làm ta tưởng nhầm nguyên nhân là biến khác.
  • Nhìn marginal, nhóm completed = Y có return nhỉnh hơn (27.4% so với 23.9%).
  • Chênh lệch này không đến từ việc hoàn thành tour.
  • Chênh lệch này đến từ 180 user aha nằm lẫn trong nhóm completed = Y (ô A, return 70%), kéo trung bình của cả nhóm lên.
  • Biến thật sự lái return là aha, không phải completion.
  • Completion chỉ tương quan gián tiếp với return, thông qua việc chứa sẵn một số user aha.
  • Cách kiểm chứng: giữ aha cố định rồi so completion trong từng chiều aha.
    • Trong nhóm aha = Y: ô A (completed = Y) return 70% so với ô C (completed = N) return 65% — gần bằng nhau.
    • Trong nhóm aha = N: ô B (completed = Y) return 10% so với ô D (completed = N) return 5% — cũng gần bằng nhau.
  • Khi aha đã cố định, completion gần như không thay đổi return.
  • Bài học Data analysis: luôn kiểm soát biến ẩn (confound) trước khi tin vào một marginal.

KPI (Key Performance Indicator — chỉ số đo hiệu quả chính):

  • Loại completion rate khỏi danh sách KPI.
  • Giữ completion rate lại như một chỉ số chẩn đoán funnel, không dùng làm KPI.
  • KPI thật là day-2 organic return rate và aha rate.

OKR North Star (OKR = Objective and Key Results — mục tiêu và các kết quả then chốt; North Star = chỉ số dẫn đường phản ánh giá trị cốt lõi):

  • Objective: user mới quay lại phiên thứ hai một cách tự nguyện vì đã hiểu sản phẩm.
  • KR1: day-2 organic return rate tăng từ 26% lên 40%.
  • KR2: aha rate (tỷ lệ user tạo khoản chi đầu tiên trong phiên đầu) tăng từ 30% lên 50%.
  • KR3: median time-to-first-expense (TTFE — thời gian trung vị từ lúc đăng ký đến khoản chi đầu tiên) giảm xuống còn tối đa 90s (hiện 120s).
  • KR4: day-7 retention (tỷ lệ còn hoạt động ở ngày thứ 7) của nhóm quay lại organic đạt tối thiểu 65% (hiện 60%).
Challenge SQL 1 — Funnel + Bảng Chéo Vanity Metric

Xây dựng báo cáo:

  • Funnel onboarding 6 bước (số user chạm tới từng bước).
  • Bảng chéo 2×2 completed × aha, kèm marginals (chỉ số biên — gộp theo từng chiều).
  • Đích cuối: dùng số liệu chứng minh completion là vanity metric (chỉ số phù phiếm) so với aha.
USE spliteven;

/* (a) FUNNEL — đếm số user chạm tới từng bước onboarding.
   Bước 1: CTE step_reach gom sự kiện theo từng bước, cộng cờ đã-chạm.
   Bước 2: query ngoài chia cho bước đông nhất để ra % so với cohort. */
WITH step_reach AS (
    SELECT s.step_no, s.step_name,                 -- số thứ tự và tên bước
           SUM(fe.reached_flag) AS users_reached   -- reached_flag = 1 nếu user chạm bước này; SUM = số user chạm
    FROM fact_onboarding_event fe
    JOIN dim_onboarding_step   s ON s.step_key = fe.step_key   -- gắn tên/số thứ tự cho mỗi sự kiện
    GROUP BY s.step_no, s.step_name                -- gom lại: mỗi bước đúng một dòng
)
SELECT step_no, step_name, users_reached,
       CAST(100.0 * users_reached
            / MAX(users_reached) OVER () AS DECIMAL(5,1)) AS pct_of_cohort
            -- MAX(...) OVER () = giá trị lớn nhất của cả cột = bước 1 = 1000 (cohort); dùng làm mẫu số
FROM step_reach
ORDER BY step_no;

/* (b) BẢNG CHÉO 2×2 + marginals bằng GROUPING SETS.
   Bước 1: mỗi CTE gộp sẵn một bảng fact về đúng một-dòng-mỗi-user.
   Bước 2: CTE flags ghép ba cờ 0/1 lại theo user_key, thiếu thì điền 0.
   Bước 3: query ngoài đếm user và returners theo từng cách gộp nhóm. */
WITH completed_flag AS (   -- một dòng mỗi user: đã chạm bước 6 hay chưa
    SELECT fe.user_key,
           MAX(CASE WHEN s.step_no = 6 THEN 1 ELSE 0 END) AS completed
    FROM fact_onboarding_event fe
    JOIN dim_onboarding_step s ON s.step_key = fe.step_key
    GROUP BY fe.user_key
),
aha_flag AS (   -- một dòng mỗi user có khoản chi đầu trong phiên đầu
    SELECT user_key, 1 AS aha
    FROM fact_expense
    WHERE is_first_session = 1
    GROUP BY user_key
),
return_flag AS (   -- một dòng mỗi user quay lại ngày 2 theo kênh organic
    SELECT user_key, 1 AS returned
    FROM fact_session
    WHERE is_day2_organic = 1
    GROUP BY user_key
),
flags AS (
    SELECT du.user_key,   -- mỗi user đúng một dòng
           CAST(ISNULL(c.completed, 0) AS TINYINT) AS completed,   -- thiếu → 0
           CAST(ISNULL(a.aha, 0)       AS TINYINT) AS aha,         -- thiếu → 0
           CAST(ISNULL(r.returned, 0)  AS TINYINT) AS returned     -- thiếu → 0 (đồng bộ với hai cờ trên)
    FROM dim_user du   -- bắt đầu từ danh sách toàn bộ user để không bỏ sót ai
    LEFT JOIN completed_flag c ON c.user_key = du.user_key   -- mỗi CTE đã một-dòng-mỗi-user nên join không phình dòng
    LEFT JOIN aha_flag       a ON a.user_key = du.user_key
    LEFT JOIN return_flag    r ON r.user_key = du.user_key
)
SELECT
    -- GROUPING(...) = 1 ở dòng đã gộp chiều đó → in 'ALL'; ngược lại in giá trị 0/1 thật
    CASE WHEN GROUPING(completed) = 1 THEN 'ALL' ELSE CAST(completed AS CHAR(1)) END AS completed,
    CASE WHEN GROUPING(aha) = 1 THEN 'ALL' ELSE CAST(aha AS CHAR(1)) END AS aha,
    COUNT(*)                                   AS users,       -- số user trong nhóm
    SUM(returned)                              AS returners,   -- số user quay lại (returned = 1)
    CAST(100.0 * SUM(returned) / COUNT(*) AS DECIMAL(5,1)) AS return_rate_pct  -- return rate của nhóm
FROM flags
GROUP BY GROUPING SETS ( (completed, aha), (completed), (aha), () )
    -- 4 cách gộp: (từng ô 2×2) · (chỉ theo completed) · (chỉ theo aha) · (toàn bộ)
ORDER BY completed, aha;

Output 01:

step_nostep_nameusers_reachedpct_of_cohort
1welcome1000100.0
2feature_overview88088.0
3how_it_works76076.0
4notification_ask70070.0
5invite_friends66066.0
6finish62062.0
  • Mỗi dòng là một bước; đọc từ trên xuống thấy số user rớt dần.
  • Dòng 1 (welcome): 1000 user — đây là cohort gốc, làm mẫu số cho cột pct_of_cohort.
  • Dòng 4 (notification_ask): còn 700 user, tức 70% cohort.
  • Dòng 6 (finish): 620 user chạm bước cuối → completion rate = 62%.

Output 02:

completedahausersreturnersreturn_rate_pctÝ nghĩa dòng
00260135.0ô D (không completed, không aha)
011207865.0ô C — An rơi vào đây
0ALL3809123.9marginal completed = N
104404410.0ô B — Chi rơi vào đây
1118012670.0ô A (vừa completed vừa aha)
1ALL62017027.4marginal completed = Y
ALL0700578.1marginal aha = N
ALL130020468.0marginal aha = Y
ALLALL100026126.1tổng toàn cohort
  • Bốn dòng không có ALL (0/0, 0/1, 1/0, 1/1) là bốn ô chi tiết của bảng 2×2.
  • So hai dòng marginal completed: 1/ALL = 27.4% và 0/ALL = 23.9%, chênh nhỏ → completion không tách được nhóm quay lại.
  • So hai dòng marginal aha: ALL/1 = 68.0% và ALL/0 = 8.1%, chênh khoảng 8 lần → aha tách rõ nhóm quay lại.
  • Dòng ALL/ALL = 26.1% là return rate trung bình của toàn cohort.
  • Kết luận: completion là vanity metric, aha mới tương quan với return.

Module 2 — Đo Tín Hiệu Aha Moment

Module 02 sẽ update vào 22:00 ngày 09/07/2026 → Các bạn theo dõi vào đọc nhé.

MÌNH ĐANG TUYỂN HỌC VIÊN CHO KHÓA HỌC THÁNG 7/2026 SQL BUSINESS CASE – PHÂN TÍCH DỮ LIỆU VỚI SQL – CASE MASTERY -> BẠN NÀO ĐĂNG KÝ INBOX MÌNH TẠI ĐÂY NHÉ. KHI ĐĂNG KÝ KHÓA HỌC, BẠN SẼ ĐƯỢC BONUS SỬ DỤNG FREE CÁC AI MODEL MỚI NHẤT NHƯ OPUS 4.8, GLM 5.2, QWEN 3.7 MAX, … ĐỂ SỬ DỤNG THOẢI MÁI TRONG VIỆC HỌC.