Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Tuần 7 • Buổi 2 — SQL cơ bản cho BA & UAT/Validation

SQL cơ bản cho BA & UAT/Validation

BA không cần viết code nhưng cần đọc được dữ liệu để đưa ra quyết định có căn cứ. SQL là ngôn ngữ phổ thông nhất để truy vấn database — và đây là kỹ năng phân biệt một BA trung bình với một BA giỏi trong môi trường làm việc thực tế.

Tại sao BA cần SQL?

Trong môi trường product thực tế, BA thường gặp các câu hỏi như:

  • "Có bao nhiêu học viên đã đăng ký khóa học trong tháng này?"
  • "Mentor nào có tỷ lệ đặt lịch cao nhất nhưng chưa có review?"
  • "Học viên nào đã thanh toán nhưng chưa hoàn thành bài học đầu tiên?"
Thay vì chờ dev trả lời hoặc tạo report tốn thời gian, BA có thể tự truy vấn (với quyền read-only) để phân tích nhanh.

SELECT & WHERE: Lọc dữ liệu cơ bản

-- Lấy danh sách học viên đăng ký từ tháng 7/2026
SELECT 
    u.id,
    u.full_name,
    u.email,
    e.enrolled_at,
    c.title AS course_title
FROM users u
JOIN enrollments e ON e.user_id = u.id
JOIN courses c ON c.id = e.course_id
WHERE e.enrolled_at >= '2026-07-01'
  AND e.enrolled_at < '2026-08-01'
ORDER BY e.enrolled_at DESC;

Giải thích cho BA:

  • SELECT — chọn cột nào cần xem (không lấy * tránh lộ dữ liệu nhạy cảm)
  • WHERE — điều kiện lọc (tương đương bộ lọc trong Excel)
  • AND / OR — kết hợp nhiều điều kiện
  • ORDER BY — sắp xếp kết quả

JOIN: Kết hợp nhiều bảng

Dữ liệu thực tế thường nằm ở nhiều bảng khác nhau. JOIN là cách "ghép" chúng lại.

-- Tìm mentor chưa có review nào sau 30 ngày được approve
SELECT 
    mp.user_id,
    u.full_name AS mentor_name,
    u.email,
    mp.approved_at,
    COUNT(mr.id) AS total_reviews
FROM mentor_profiles mp
JOIN users u ON u.id = mp.user_id
LEFT JOIN mentor_reviews mr ON mr.mentor_id = mp.user_id
WHERE mp.approved_at IS NOT NULL
  AND mp.approved_at < DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY mp.user_id, u.full_name, u.email, mp.approved_at
HAVING COUNT(mr.id) = 0
ORDER BY mp.approved_at ASC;

Các loại JOIN BA cần biết:

  • INNER JOIN (hoặc chỉ JOIN): chỉ lấy hàng khớp cả hai bảng
  • LEFT JOIN: lấy tất cả hàng từ bảng trái, bảng phải có thể NULL — dùng khi muốn tìm "những gì chưa có" (ví dụ: mentor chưa có review)

GROUP BY & Aggregate Functions: Tổng hợp dữ liệu

-- Doanh thu theo khóa học trong Q3/2026
SELECT 
    c.title AS course_title,
    c.category,
    COUNT(DISTINCT e.user_id) AS total_students,
    COUNT(DISTINCT CASE WHEN lp.completed_at IS NOT NULL THEN lp.user_id END) AS completed_students,
    ROUND(
        COUNT(DISTINCT CASE WHEN lp.completed_at IS NOT NULL THEN lp.user_id END) * 100.0 
        / NULLIF(COUNT(DISTINCT e.user_id), 0), 
    1) AS completion_rate_pct
FROM courses c
JOIN enrollments e ON e.course_id = c.id
LEFT JOIN (
    SELECT user_id, course_id, MAX(completed_at) AS completed_at
    FROM lesson_progress
    WHERE is_final_lesson = 1
    GROUP BY user_id, course_id
) lp ON lp.course_id = c.id AND lp.user_id = e.user_id
WHERE e.enrolled_at BETWEEN '2026-07-01' AND '2026-09-30'
GROUP BY c.id, c.title, c.category
HAVING COUNT(DISTINCT e.user_id) >= 5
ORDER BY completion_rate_pct DESC;

Aggregate functions hay dùng:

  • COUNT(*) — đếm số hàng
  • COUNT(DISTINCT col) — đếm giá trị không trùng
  • SUM(col) — tổng
  • AVG(col) — trung bình
  • MAX/MIN(col) — giá trị lớn nhất/nhỏ nhất
  • HAVING — lọc sau khi GROUP BY (khác WHERE: WHERE lọc trước khi group)

Best Practice cho BA khi dùng SQL

  • Luôn dùng LIMIT khi explore: SELECT * FROM users LIMIT 100 — tránh kéo hàng triệu hàng
  • Đặt alias rõ ràng: u.full_name AS mentor_name giúp đọc kết quả dễ hơn
  • Comment SQL: giải thích business logic phức tạp ngay trong query
  • Không UPDATE/DELETE: BA chỉ nên có quyền SELECT — nếu vô tình có quyền cao hơn, tuyệt đối không dùng
  • Lưu query vào file: đặt tên rõ 2026-07-mentor-no-reviews.sql

Test Case: Nền tảng của UAT

Test case là tài liệu mô tả chính xác cách kiểm tra một chức năng. Đây là công cụ chính của BA trong giai đoạn UAT (User Acceptance Testing).

Cấu trúc một test case:

TrườngMô tả
Test Case IDTC-001
Tên chức năngĐặt lịch mentor
Điều kiện tiên quyếtHọc viên đã đăng nhập, mentor có lịch trống
Bước thực hiện1. Vào trang mentor / 2. Chọn khung giờ / 3. Điền ghi chú / 4. Click Xác nhận
Dữ liệu testNgày: 2026-08-01 10:00, Ghi chú: "Tư vấn CV"
Kết quả mong đợiEmail xác nhận gửi đến học viên trong 2 phút, booking xuất hiện trong lịch mentor
Kết quả thực tế(điền sau khi test)
Pass/Fail(điền sau khi test)

Validation vs Verification

Đây là hai khái niệm hay bị nhầm lẫn:

  • Verification (Kiểm chứng): "Chúng ta có đang BUILD đúng không?" — kiểm tra sản phẩm so với spec/requirement. Ví dụ: form đăng ký có đủ 5 trường như spec không?
  • Validation (Xác nhận): "Chúng ta có đang BUILD đúng thứ không?" — kiểm tra sản phẩm có giải quyết được vấn đề của người dùng không. Ví dụ: học viên có thực sự đặt được lịch dễ dàng không?
Công thức nhớ nhanh:
  • Verification = so với tài liệu (spec, AC)
  • Validation = so với người dùng thật (usability test, user interview)
UAT (User Acceptance Testing) là hoạt động validation — người dùng thật thực hiện test để xác nhận sản phẩm đáp ứng nhu cầu thực tế.

Tự luyện

  • Truy cập SQL playground (sql.js hoặc DB Fiddle), tạo bảng users, courses, enrollments với 10 hàng mẫu. Viết 3 query: (a) đếm học viên theo khóa học, (b) tìm học viên chưa hoàn thành khóa học nào, (c) tỷ lệ hoàn thành theo danh mục.
  • Chọn một tính năng bạn đang dùng hàng ngày (ví dụ: đăng nhập bằng Google). Viết 5 test case bao gồm: happy path, email sai, tài khoản bị khóa, mất kết nối mạng, đăng nhập lần đầu.
  • Phân biệt: tính năng "form đăng ký có đủ trường" là verification hay validation? Tại sao?
Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi