Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn đang ngồi trong một cuộc họp refinement. Product Owner đề xuất một tính năng: "Cho phép khách hàng hủy đơn hàng trong vòng 30 phút sau khi đặt". Nghe rất hợp lý. Nhưng bạn — với vai trò Business Analyst — buộc phải đặt câu hỏi: thực tế có bao nhiêu khách hủy đơn trong 30 phút đầu? Tỷ lệ đó là 2% hay 40%? Nếu là 2%, tính năng này có đáng để team bỏ ra hai sprint không?
Trong rất nhiều tổ chức, câu trả lời sẽ là: "Để tôi nhờ team data lấy số liệu, vài hôm nữa có". Và thế là quyết định bị treo, momentum bị mất, đôi khi tính năng được duyệt chỉ vì cảm tính chứ không phải vì dữ liệu.
Một BA biết SQL sẽ khác hẳn. Ngay trong cuộc họp, bạn mở laptop, gõ một câu truy vấn vào read-replica của database, và hai phút sau bạn nói: "Trong 90 ngày qua, chỉ 1.8% đơn bị hủy trong 30 phút đầu, nhưng 12% bị hủy trong 24 giờ đầu — vậy cửa sổ hủy nên là 24 giờ chứ không phải 30 phút". Khoảnh khắc đó, bạn không còn là người chuyển tiếp yêu cầu nữa. Bạn trở thành người định hình quyết định.
Đó chính là lý do bài này tồn tại. SQL không biến BA thành kỹ sư dữ liệu, và bạn cũng không cần trở thành kỹ sư. Nhưng SQL cho bạn một thứ vô giá: khả năng tự kiểm chứng giả định bằng dữ liệu thật, thay vì phụ thuộc vào người khác và những con số được nghe lại qua nhiều lớp. Trong bài này, chúng ta tập trung đúng vào kỹ năng phân tích dữ liệu và SQL ở mức một BA cần — đủ để tự đứng vững, không lan sang viết SELECT/JOIN nâng cao hay window function (những phần đó sẽ có bài riêng), mà tập trung vào tư duy phân tích dữ liệu và cách BA dùng dữ liệu để làm việc tốt hơn.
Khái niệm cốt lõi
BA cần SQL để làm gì, cụ thể?
Có ba nhóm công việc mà SQL trực tiếp giúp một BA mạnh hơn hẳn.
Thứ nhất — Tự verify dữ liệu thay vì chờ dev/data analyst. Khi viết requirement, bạn thường giả định về cấu trúc và chất lượng dữ liệu hiện tại. "Mỗi khách hàng có một số điện thoại duy nhất". Thật không? Một câu truy vấn đếm số bản ghi trùng phone sẽ cho bạn biết ngay rằng có 3.400 khách hàng dùng chung số điện thoại — và đó là một edge case bạn phải thiết kế xử lý. Không có SQL, bạn sẽ phát hiện điều này ở giai đoạn UAT, khi sửa đã đắt gấp mười lần.
Thứ hai — Validate requirement bằng dữ liệu thực tế. Stakeholder thường nói bằng cảm nhận: "Phần lớn khách hàng của chúng ta ở Hà Nội và TP.HCM". BA giỏi sẽ kiểm chứng. Có thể thực tế là 55% ở hai thành phố này, nhưng 18% ở Đà Nẵng và Cần Thơ — đủ lớn để quyết định mở rộng giao hàng. Dữ liệu biến giả định mơ hồ thành con số có thể tranh luận.
Thứ ba — Tạo báo cáo cho stakeholder. Không phải lúc nào cũng cần dashboard hoành tráng. Đôi khi stakeholder chỉ cần một bảng số gọn gàng: doanh thu theo tháng, số ticket theo nhóm nguyên nhân, tỷ lệ chuyển đổi theo kênh. Một BA biết SQL có thể tự kéo những con số này trong vài phút, thay vì gửi yêu cầu và chờ đợi.
Read-only là nguyên tắc sống còn
Đây là điều quan trọng nhất về mặt an toàn mà mọi BA phải khắc cốt ghi tâm: bạn chỉ đọc, không bao giờ ghi. Công việc của BA với SQL gói gọn trong câu lệnh SELECT — lấy dữ liệu ra để xem. Bạn tuyệt đối không chạy UPDATE, DELETE, INSERT hay DROP trên database production. Lý tưởng nhất, bạn được cấp một tài khoản chỉ có quyền đọc (read-only account) và truy vấn trên read-replica — một bản sao của database thật, được tạo ra riêng cho việc đọc, để truy vấn của bạn không làm chậm hệ thống đang phục vụ khách hàng.
Một anh BA junior ở một ví điện tử từng chạy nhầm một câu SELECT không có điều kiện WHERE trên bảng giao dịch 400 triệu dòng, vào đúng giờ cao điểm, khiến database chậm hẳn. Anh ta không xóa gì cả, nhưng vẫn gây gián đoạn. Bài học: ngay cả việc đọc cũng cần kỷ luật.
Bốn thành phần của một câu truy vấn mà BA phải hiểu
Bạn không cần thuộc lòng cú pháp, nhưng phải hiểu ý nghĩa của bốn mảnh ghép:
- SELECT — chọn những cột (thông tin) bạn muốn xem. Ví dụ: tên khách, ngày đặt hàng, tổng tiền.
- FROM — chỉ định bảng dữ liệu lấy từ đâu. Ví dụ: bảng
orders. - WHERE — lọc điều kiện. Ví dụ: chỉ lấy đơn trong tháng 5, chỉ lấy đơn đã thanh toán.
- GROUP BY — gom nhóm để tính tổng/đếm/trung bình. Ví dụ: gom theo từng tỉnh để đếm số đơn mỗi tỉnh.
Phân tích dữ liệu không chỉ là lấy số — mà là đặt đúng câu hỏi
Kỹ năng cốt lõi nhất của BA không phải là gõ SQL nhanh, mà là chuyển một câu hỏi nghiệp vụ mơ hồ thành một câu hỏi dữ liệu rõ ràng. "Khách hàng có hài lòng không?" là câu hỏi nghiệp vụ. Nó không truy vấn được. Bạn phải dịch nó thành: "Tỷ lệ khách quay lại mua lần hai trong 60 ngày là bao nhiêu?" hoặc "Điểm CSAT trung bình theo tháng có xu hướng tăng hay giảm?". Đây là bước tư duy quan trọng nhất, và nó hoàn toàn độc lập với việc bạn dùng công cụ gì.
Tình huống thực tế
Tình huống 1 — Tiki và giả định về "khách bỏ giỏ hàng"
Giả định bối cảnh tại một sàn thương mại điện tử lớn như Tiki. Marketing đề xuất chi 500 triệu đồng cho chiến dịch email nhắc nhở những khách "bỏ giỏ hàng" (thêm sản phẩm vào giỏ nhưng không thanh toán), với lập luận: "Hàng nghìn khách bỏ giỏ mỗi ngày, chỉ cần kéo lại 10% là lãi to".
BA được giao đánh giá tính khả thi của requirement. Thay vì chấp nhận con số "hàng nghìn", anh viết một câu truy vấn đơn giản: đếm số session có thêm hàng vào giỏ nhưng không có đơn hoàn tất, nhóm theo ngày, trong 30 ngày qua. Kết quả: trung bình 8.200 giỏ bị bỏ mỗi ngày — đúng là lớn. Nhưng anh đào sâu thêm một câu nữa: lọc ra những giỏ có giá trị trên 200.000 đồng và khách có để lại email. Con số tụt xuống còn 1.100/ngày. Phần còn lại là khách vãng lai không có email để gửi, hoặc giỏ giá trị quá nhỏ không đáng chi phí gửi mail.
Bài học: Con số tổng (8.200) khiến requirement nghe hấp dẫn. Con số sau khi lọc đúng đối tượng có thể tác động (1.100) mới là cơ sở để tính ROI thật. BA biết SQL đã ngăn một quyết định dựa trên con số bị thổi phồng, và đề xuất một phiên bản chiến dịch nhắm đúng hơn.
Tình huống 2 — Ngân hàng VPBank và chất lượng dữ liệu eKYC
Bối cảnh giả định tại một ngân hàng đang triển khai mở tài khoản online. Requirement ban đầu viết: "Hệ thống dùng số CMND/CCCD làm định danh duy nhất cho mỗi khách hàng". Nghe rất chuẩn về mặt nghiệp vụ.
BA quyết định kiểm chứng trên dữ liệu khách hàng hiện hữu trước khi chốt requirement. Cô chạy một truy vấn đếm số khách hàng theo từng số định danh và lọc ra những số xuất hiện nhiều hơn một lần (GROUP BY số định danh, rồi HAVING COUNT > 1). Kết quả gây sốc: hơn 14.000 khách hàng có số định danh trùng nhau. Đào sâu, cô phát hiện ba nguyên nhân: khách cũ dùng CMND 9 số, sau đó đổi sang CCCD 12 số nên tạo ra hai bản ghi; một số bản ghi nhập sai do nhân viên gõ tay; và một nhóm khách có cùng giá trị mặc định "000000000" do hệ thống cũ để trống.
Bài học: Nếu requirement "định danh duy nhất" được code thẳng mà không xử lý ba trường hợp này, hệ thống mới sẽ từ chối hàng nghìn khách hợp lệ hoặc gộp nhầm hai người thành một — một rủi ro nghiêm trọng với ngân hàng. Nhờ verify bằng SQL, BA bổ sung được các business rule xử lý chuyển đổi CMND-CCCD và làm sạch dữ liệu trước khi migrate. Đây là loại giá trị mà không một buổi phỏng vấn stakeholder nào mang lại được — chỉ dữ liệu thật mới phơi bày.
Tình huống 3 — Grab và báo cáo tự phục vụ cho cuộc họp
Bối cảnh giả định tại một nền tảng gọi xe. Mỗi đầu tuần, Head of Operations cần biết: tỷ lệ chuyến bị hủy theo từng thành phố, để quyết định nơi nào cần thêm tài xế. Trước đây, yêu cầu này gửi sang team data và mất 2-3 ngày mới có kết quả, thường thì đã trễ so với cuộc họp.
BA của team Operations học một câu SQL duy nhất: gom các chuyến theo thành phố, đếm tổng số chuyến và số chuyến bị hủy, rồi tính tỷ lệ. Anh lưu câu truy vấn này lại và mỗi sáng thứ Hai chỉ cần chạy lại, mất chưa tới một phút. Báo cáo luôn sẵn sàng trước cuộc họp. Quan trọng hơn, vì anh hiểu rõ con số được tính thế nào, anh trả lời được ngay khi sếp hỏi "Đà Nẵng tăng đột biến là do đâu?" — anh thêm điều kiện lọc theo khung giờ và phát hiện hủy tập trung vào giờ tan tầm khi thiếu tài xế.
Bài học: SQL biến BA từ người chờ báo cáo thành người làm chủ báo cáo. Khả năng tự kéo và đào sâu số liệu ngay tại chỗ làm thay đổi vị thế của BA trong cuộc họp — từ người ghi chép thành người dẫn dắt phân tích.
Hướng dẫn từng bước
Đây là quy trình để một BA bắt đầu dùng SQL trong công việc thật, theo đúng thứ tự.
Bước 1 — Xin quyền truy cập read-only. Liên hệ team data/DBA xin một tài khoản chỉ-đọc và yêu cầu được kết nối vào read-replica chứ không phải database production. Hỏi rõ: tôi được phép truy vấn những bảng nào? Giờ nào nên tránh? Đây là bước thiết lập an toàn, đừng bỏ qua.
Bước 2 — Lấy data dictionary / sơ đồ bảng. Trước khi viết truy vấn, bạn phải biết dữ liệu nằm ở đâu. Xin tài liệu mô tả các bảng (data dictionary) và mối quan hệ giữa chúng. Bảng orders có cột gì? Cột status nhận những giá trị nào — paid, cancelled, refunded? Hiểu ý nghĩa từng cột quan trọng hơn nhiều so với việc thuộc cú pháp.
Bước 3 — Bắt đầu bằng câu hỏi nghiệp vụ, không phải bằng SQL. Viết ra giấy câu hỏi bạn cần trả lời bằng tiếng Việt: "Tháng 5 có bao nhiêu đơn đã thanh toán, theo từng tỉnh?". Chỉ khi câu hỏi rõ, bạn mới dịch sang SQL.
Bước 4 — Viết truy vấn từ nhỏ đến lớn. Đừng viết câu phức tạp ngay. Bắt đầu bằng SELECT * FROM orders LIMIT 10 để xem dữ liệu trông thế nào. Thêm WHERE để lọc tháng 5. Thêm điều kiện trạng thái paid. Cuối cùng mới thêm GROUP BY tỉnh và COUNT. Mỗi lần thêm một mảnh, chạy lại để chắc chắn nó đúng.
Bước 5 — Luôn dùng LIMIT khi thăm dò. Khi mới khám phá một bảng lạ, luôn thêm LIMIT 100 để không vô tình kéo hàng triệu dòng. Đây là thói quen bảo vệ cả bạn lẫn hệ thống.
Bước 6 — Kiểm chứng chéo kết quả (sanity check). Số bạn ra có hợp lý không? Nếu truy vấn nói tháng 5 có 3 đơn nhưng bạn biết công ty bán hàng nghìn đơn mỗi ngày, chắc chắn câu lọc của bạn sai ở đâu đó. Luôn đối chiếu kết quả với hiểu biết nghiệp vụ.
Bước 7 — Lưu lại và ghi chú truy vấn. Khi có một câu hỏi lặp lại hằng tuần, lưu câu SQL kèm một dòng comment giải thích nó tính gì. Lần sau chỉ cần chạy lại.
Lỗi thường gặp & mẹo
Lỗi 1 — Quên lọc trạng thái. Đây là lỗi kinh điển. Bạn đếm "số đơn hàng tháng 5" nhưng quên loại bỏ đơn bị hủy và đơn hoàn tiền. Con số doanh thu bị thổi phồng. Luôn hỏi: tôi đang tính trên toàn bộ bản ghi hay chỉ những bản ghi hợp lệ? Trạng thái (status) gần như luôn cần được lọc.
Lỗi 2 — Nhầm lẫn giữa COUNT() và COUNT(DISTINCT). COUNT() đếm số dòng; COUNT(DISTINCT customer_id) đếm số khách hàng riêng biệt. Một khách mua 5 lần sẽ làm hai con số này khác nhau hoàn toàn. Khi sếp hỏi "có bao nhiêu khách hàng", bạn cần con số distinct, không phải số dòng.
Lỗi 3 — Hiểu sai NULL. Ô trống (NULL) không bằng 0 và cũng không bằng chuỗi rỗng. Lọc WHERE phone != '' sẽ bỏ sót những dòng phone là NULL. Khi phân tích dữ liệu thiếu, hãy chủ động kiểm tra WHERE phone IS NULL để biết có bao nhiêu bản ghi trống.
Lỗi 4 — Tin con số đầu tiên ra được. Truy vấn chạy thành công không có nghĩa là kết quả đúng. Logic lọc sai vẫn cho ra một con số trông hợp lý. Luôn sanity check.
Mẹo 1 — Học bằng câu hỏi thật của công việc bạn. Đừng học SQL qua dữ liệu mẫu nhàm chán. Lấy đúng câu hỏi mà stakeholder của bạn hay hỏi và tập trả lời bằng SQL. Động lực và độ ghi nhớ sẽ cao hơn nhiều.
Mẹo 2 — Nhờ data analyst review câu truy vấn quan trọng. Trước khi đưa một con số vào báo cáo cấp lãnh đạo, nhờ một người trong team data liếc qua câu SQL của bạn. Mất 5 phút của họ, tránh cho bạn báo cáo sai số liệu cho ban giám đốc.
Mẹo 3 — Trao đổi với dev/DBA bằng ngôn ngữ dữ liệu. Khi bạn biết SQL, các cuộc trao đổi với kỹ thuật trở nên chính xác hơn nhiều. Thay vì "khách hàng", bạn nói "bản ghi trong bảng customers có status = active". Sự chính xác này giảm hiểu nhầm và rút ngắn vòng lặp làm việc.
Bài tập thực hành
Hãy hình dung bạn là BA của một sàn thương mại điện tử với hai bảng chính: orders (đơn hàng, gồm cột order_id, customer_id, order_date, province, status, total_amount) và customers (khách hàng, gồm customer_id, full_name, phone, created_date, city).
- Dịch câu hỏi nghiệp vụ thành câu hỏi dữ liệu. Stakeholder nói: "Tôi muốn biết miền nào đang mua nhiều nhất". Hãy viết ra (bằng lời) câu hỏi dữ liệu rõ ràng tương ứng — bạn sẽ nhóm theo gì, đếm gì, lọc trạng thái nào, trong khoảng thời gian nào?
- Phác câu truy vấn. Viết câu SQL đếm số đơn hàng đã thanh toán (
status = 'paid') trong tháng 5, nhóm theoprovince, sắp xếp giảm dần. Bạn chưa cần chạy được — chỉ cần ghép đúng SELECT, FROM, WHERE, GROUP BY.
- Tìm vấn đề chất lượng dữ liệu. Viết (bằng lời hoặc SQL) cách bạn kiểm tra xem có bao nhiêu khách hàng bị trùng số điện thoại trong bảng
customers. Gợi ý: gom theophone, đếm, giữ lại những nhóm có số đếm lớn hơn 1.
- Bẫy NULL. Giải thích vì sao truy vấn đếm khách "không có số điện thoại" bằng
WHERE phone = ''có thể cho kết quả sai, và bạn sẽ sửa thế nào.
- Sanity check. Truy vấn của bạn trả về: TP.HCM 4.200 đơn, Hà Nội 3.800 đơn, và "tỉnh trống (NULL)" 9.500 đơn. Con số NULL lớn bất thường nói lên điều gì về dữ liệu, và bạn sẽ báo cáo điều này với stakeholder ra sao?
Tóm tắt
SQL không biến bạn thành lập trình viên, nhưng nó biến bạn thành một BA độc lập về dữ liệu. Ba giá trị cốt lõi: tự verify dữ liệu thay vì chờ người khác, validate requirement bằng số liệu thật thay vì cảm tính, và tự tạo báo cáo để dẫn dắt cuộc họp. Nguyên tắc an toàn tối thượng là chỉ-đọc: dùng tài khoản read-only trên read-replica, không bao giờ ghi vào production. Bốn mảnh ghép SELECT — FROM — WHERE — GROUP BY đủ để trả lời phần lớn câu hỏi nghiệp vụ hằng ngày. Nhưng kỹ năng quan trọng nhất không phải cú pháp, mà là khả năng dịch một câu hỏi nghiệp vụ mơ hồ thành một câu hỏi dữ liệu rõ ràng, rồi luôn sanity check kết quả trước khi tin vào nó. Như ba tình huống của Tiki, ngân hàng và Grab cho thấy: con số tổng dễ đánh lừa, dữ liệu thật phơi bày edge case, và một câu truy vấn đúng lúc có thể thay đổi cả một quyết định. Hãy bắt đầu từ chính những câu hỏi mà stakeholder của bạn đang hỏi mỗi ngày.