Menu
ESC

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

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

Đang tải...

JQL và Reporting

JIRA and Confluence for BA Bài 2/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là BA trong một dự án có hơn 2.000 issue đang nằm rải rác trong JIRA. Sếp hỏi: "Tuần này team mình còn bao nhiêu bug chưa fix thuộc module thanh toán, ai đang ôm, và có cái nào quá hạn không?" Nếu bạn ngồi click từng bộ lọc, kéo thả, lật từng trang, bạn sẽ mất cả buổi chiều — và đến lúc trả lời thì con số đã cũ.

JQL (JIRA Query Language) sinh ra để giải quyết đúng nỗi đau đó. Nó là ngôn ngữ truy vấn cho phép bạn "hỏi" JIRA bằng một câu lệnh ngắn gọn, và nhận về đúng tập issue bạn cần — chính xác, tức thì, và có thể tái sử dụng. Với một BA, JQL không phải là kỹ năng "có thì tốt", mà là công cụ làm việc hằng ngày: lọc backlog, theo dõi tiến độ, soi chất lượng, và quan trọng nhất là biến dữ liệu thô trong JIRA thành báo cáo (reporting) mà người ra quyết định có thể đọc được.

Trong bài này, chúng ta sẽ nắm ý tưởng cốt lõi của JQL ở mức nền tảng — cấu trúc một câu truy vấn, các toán tử và hàm thông dụng — rồi gắn liền nó với câu chuyện reporting: làm sao từ một filter biến thành con số trên dashboard, thành báo cáo gửi sếp. Đây là bài đặt nền móng; các bài sau sẽ đào sâu JQL cơ bản, JQL nâng cao và các loại report chuyên biệt. Ở đây, mục tiêu của bạn là hiểu được "bộ khung tư duy": JQL hoạt động như thế nào và vì sao nó là trái tim của mọi báo cáo trong JIRA.

Khái niệm cốt lõi

JQL là gì và nó khác gì với ô search thông thường

JIRA có một ô tìm kiếm cơ bản (basic search) với các dropdown để chọn project, status, assignee... Nhưng cách đó nhanh chóng đụng trần khi điều kiện phức tạp lên. JQL là chế độ advanced search, nơi bạn gõ trực tiếp một câu lệnh dạng văn bản. Hãy nghĩ về nó giống như câu lệnh SQL nhưng dành riêng cho issue: thay vì truy vấn bảng dữ liệu, bạn truy vấn tập hợp issue.

Một câu JQL được ghép từ ba thành phần:

  • Field (trường): thuộc tính của issue, ví dụ project, status, assignee, priority, created, type.
  • Operator (toán tử): cách so sánh, ví dụ =, !=, >, <, IN, NOT IN, ~ (chứa), IS EMPTY.
  • Value (giá trị): giá trị cần so, ví dụ "In Progress", Bug, một username, một ngày.
Ghép lại thành mệnh đề: status = "In Progress". Khi nối nhiều mệnh đề, ta dùng toán tử logic AND, OR, NOT, và sắp xếp bằng ORDER BY.

Cấu trúc một câu truy vấn cơ bản

Hãy mổ xẻ ví dụ trong dàn ý:

project = MYPROJECT AND status = "In Progress"

Câu này đọc là: "Lấy tất cả issue thuộc project MYPROJECT đang ở trạng thái In Progress." Lưu ý: giá trị có khoảng trắng như In Progress phải đặt trong dấu ngoặc kép.

assignee = currentUser() AND sprint in openSprints()

Câu này tinh tế hơn: nó dùng hai hàm (function). currentUser() tự trả về chính người đang đăng nhập, còn openSprints() trả về các sprint đang mở. Nghĩa là: "Việc đang giao cho tôi, nằm trong các sprint đang chạy." Cái hay là câu này không cần sửa khi người khác dùng — ai mở filter cũng thấy việc của chính họ. Đây là nền tảng cho mọi "My Open Issues" filter.

type = Bug

Đơn giản nhất: lấy mọi issue loại Bug.

Toán tử thường dùng cho BA

  • =!=: bằng / khác. priority = High, status != Done.
  • INNOT IN: thuộc / không thuộc một danh sách. status IN ("To Do", "In Progress") gọn hơn nhiều so với viết OR lặp lại.
  • ~ (contains): tìm văn bản chứa từ khóa. summary ~ "thanh toán" tìm issue có chữ "thanh toán" trong tiêu đề.
  • IS EMPTY / IS NOT EMPTY: kiểm tra trường có giá trị hay không. fixVersion IS EMPTY tìm issue chưa gán version.
  • >, <, >=, <=: dùng cho ngày và số. created >= "2026-06-01".

Hàm — nơi JQL trở nên mạnh mẽ

Hàm (function) làm cho truy vấn "sống" theo thời gian thực. Vài hàm quan trọng:

  • currentUser() — người đang đăng nhập.
  • openSprints() / closedSprints() — sprint đang mở / đã đóng.
  • startOfWeek(), startOfMonth(), endOfDay(), now() — các mốc thời gian tương đối. Ví dụ created >= startOfWeek() luôn nghĩa là "từ đầu tuần này", không cần sửa ngày mỗi tuần.
  • membersOf("ten-group") — thành viên của một group, dùng để lọc theo cả nhóm.

Từ JQL đến Reporting

Đây là mắt xích quan trọng nhất của bài. Một câu JQL bản thân nó chỉ trả về danh sách issue. Nhưng khi bạn lưu nó lại thành một filter (Save as filter), nó trở thành một "ống dữ liệu" có tên. Và mọi cơ chế báo cáo trong JIRA đều ăn từ filter:

  • Bạn gắn filter vào gadget trên dashboard để hiện con số, biểu đồ.
  • Bạn dùng filter làm nguồn cho board, cho report tích hợp.
  • Bạn export filter ra Excel/CSV để dựng báo cáo tay.
  • Bạn dùng cơ chế đếm: cùng một filter, đổi status là ra "tỷ lệ hoàn thành".
Nói cách khác: JQL là câu hỏi, filter là câu hỏi được đặt tên, reporting là cách trình bày câu trả lời. Hiểu chuỗi này, bạn sẽ thấy vì sao một BA giỏi JQL có thể tự dựng được hệ thống theo dõi dự án mà không phụ thuộc vào ai.

Tình huống thực tế

Tình huống 1 — Tiki và bài toán bug tồn đọng cuối sprint

Một team phát triển tại một công ty thương mại điện tử lớn ở TP.HCM (tạm gọi mô hình Tiki) chạy sprint hai tuần. Cuối mỗi sprint, Product Owner luôn cần biết: còn bao nhiêu bug chưa đóng thuộc sprint hiện tại, mức độ ưu tiên ra sao. BA trong team viết:

project = SHOP AND type = Bug AND status != Done AND sprint in openSprints() ORDER BY priority DESC

Câu này trả về đúng các bug chưa Done trong sprint đang chạy, sắp xếp ưu tiên cao xuống thấp. BA lưu nó thành filter tên "Open Bugs — Current Sprint", gắn lên dashboard team dưới dạng một gadget đếm số. Kết quả: thay vì mỗi buổi standup phải lục lọi, cả team nhìn lên màn hình là thấy con số — ví dụ "12 bug, trong đó 3 High".

Bài học rút ra: hàm openSprints() khiến filter này không bao giờ lỗi thời. Sang sprint mới, nó tự trỏ vào sprint mới, không cần ai sửa. Một câu JQL viết đúng có thể phục vụ cả năm.

Tình huống 2 — Ngân hàng số và báo cáo SLA quá hạn

Một dự án chuyển đổi số tại một ngân hàng (tạm gọi mô hình TPBank) yêu cầu mọi yêu cầu nghiệp vụ phải được xử lý trong 5 ngày làm việc. BA cần một báo cáo hằng tuần liệt kê các issue "quá hạn" — tạo cách đây hơn 5 ngày mà vẫn chưa đóng. Cô viết:

project = CORE AND status not in (Done, Closed, Resolved) AND created <= -5d ORDER BY created ASC

Ở đây created <= -5d nghĩa là "được tạo từ cách đây 5 ngày trở về trước" — một cách viết thời gian tương đối rất gọn. ORDER BY created ASC đẩy issue cũ nhất (tồn lâu nhất) lên đầu để xử lý trước. BA export filter này ra Excel mỗi sáng thứ Hai, đính kèm số liệu vào email báo cáo cho ban lãnh đạo: tuần đó có 8 issue quá hạn, issue cũ nhất đã tồn 11 ngày.

Bài học rút ra: thời gian tương đối (-5d, startOfWeek()) biến một câu JQL thành một "báo cáo tự cập nhật". Bạn viết một lần, dùng mỗi tuần, và con số luôn đúng với thời điểm chạy.

Tình huống 3 — Startup fintech Singapore và dashboard "ai đang gánh việc"

Một startup fintech ở Singapore có 4 team chạy chung một JIRA. Trưởng nhóm BA muốn biết khối lượng việc phân bổ ra sao để tránh ai đó quá tải. Anh dựng một loạt filter dựa trên cùng khuôn:

project = PAY AND assignee = membersOf("team-payments") AND status = "In Progress"

Rồi nhân bản cho từng team (team-onboarding, team-risk...). Mỗi filter gắn vào một gadget "Two Dimensional Filter Statistics" trên dashboard, chia theo assigneestatus. Nhìn vào bảng, anh thấy ngay một bạn trong team risk đang ôm 9 việc In Progress trong khi đồng đội chỉ 2-3 — dấu hiệu cần phân bổ lại.

Bài học rút ra: membersOf() cho phép báo cáo theo cả nhóm thay vì gõ tay từng tên. Khi nhân sự thay đổi, chỉ cần cập nhật group, mọi filter và dashboard tự cập nhật theo. Đây là cách reporting "scale" được khi team lớn dần.

Hướng dẫn từng bước

Hãy cùng đi qua quy trình từ con số 0 đến một báo cáo hoàn chỉnh.

Bước 1 — Mở Advanced Search. Vào menu Filters → Advanced issue search (hoặc View all issues). Nếu đang ở chế độ basic, bấm liên kết Switch to JQL để chuyển sang ô gõ JQL.

Bước 2 — Viết mệnh đề đầu tiên. Bắt đầu hẹp: gõ project = và để JIRA gợi ý tên project. Tận dụng tính năng autocomplete — JIRA gợi ý field, operator và cả value hợp lệ ngay khi bạn gõ. Đây là cách học JQL nhanh nhất.

Bước 3 — Thêm điều kiện bằng AND/OR. Nối thêm: AND status = "In Progress". Bấm Enter để chạy và xem kết quả. Cứ thêm từng điều kiện một và chạy lại để kiểm tra — đừng viết cả câu dài rồi mới chạy.

Bước 4 — Sắp xếp. Thêm ORDER BY priority DESC hoặc ORDER BY created ASC để kết quả có thứ tự ý nghĩa cho người đọc báo cáo.

Bước 5 — Lưu thành filter. Khi hài lòng, bấm Save as và đặt tên rõ ràng theo quy ước, ví dụ "[SHOP] Open Bugs — Current Sprint". Tên tốt giúp cả team tìm lại và không tạo trùng.

Bước 6 — Chia sẻ filter. Trong phần quyền của filter, chọn chia sẻ với project hoặc group phù hợp, để đồng đội dùng chung thay vì mỗi người viết lại.

Bước 7 — Đưa filter vào reporting. Tạo một dashboard mới, Add gadget, chọn gadget phù hợp (Filter Results để liệt kê, Pie Chart để chia theo trạng thái, Two Dimensional Filter Statistics để lập bảng chéo), rồi trỏ gadget tới filter vừa lưu. Giờ thì câu JQL của bạn đã thành một báo cáo trực quan, tự cập nhật mỗi khi mở dashboard.

Bước 8 — Export khi cần báo cáo tĩnh. Từ kết quả filter, dùng Export → CSV/Excel để tạo bản báo cáo đính kèm email hoặc đưa vào slide tổng kết.

Lỗi thường gặp & mẹo

Quên dấu ngoặc kép cho giá trị có khoảng trắng. Viết status = In Progress sẽ báo lỗi; phải là status = "In Progress". Quy tắc: giá trị có khoảng trắng hoặc ký tự đặc biệt thì bọc trong ngoặc kép.

Nhầm = với ~. summary = "thanh toán" chỉ khớp khi tiêu đề đúng y hệt chuỗi đó. Muốn tìm "chứa từ khóa", dùng ~: summary ~ "thanh toán". Đây là lỗi rất phổ biến khiến truy vấn trả về rỗng dù bạn chắc chắn có issue.

Lạm dụng AND/OR mà quên dấu ngoặc đơn. JQL ưu tiên AND trước OR, nên status = Done OR status = Closed AND project = SHOP không có nghĩa như bạn tưởng. Hãy nhóm rõ bằng ngoặc: (status = Done OR status = Closed) AND project = SHOP.

Dùng ngày cố định cho báo cáo định kỳ. Viết created >= "2026-06-01" thì tuần sau con số vẫn tính từ mốc cũ. Với báo cáo lặp lại, hãy dùng thời gian tương đối: startOfWeek(), startOfMonth(), -7d. Filter sẽ tự đúng theo thời điểm chạy.

Mẹo dùng autocomplete làm "từ điển". Khi không nhớ tên field hay function, cứ gõ vài ký tự và để JIRA gợi ý. Đây là cách an toàn nhất để dùng đúng tên trường tùy biến (custom field) trong từng instance.

Mẹo đặt tên filter có tiền tố project. Đặt [SHOP] ..., [CORE] ... giúp danh sách filter dễ tìm khi team có hàng trăm filter, và tránh người khác vô tình sửa nhầm filter của bạn.

Mẹo kiểm tra bằng cách đảo điều kiện. Nghi ngờ filter sót issue? Chạy thử phiên bản ngược (status = Done thay vì != Done) và cộng hai con số lại xem có khớp tổng không. Đây là cách "đối chiếu" đơn giản để tin vào báo cáo của mình.

Bài tập thực hành

Hãy mở JIRA (hoặc một site Atlassian dùng thử miễn phí) và tự tay viết các truy vấn sau. Mục tiêu là gõ được, chạy ra kết quả, và lưu thành filter.

  • Viết JQL lấy tất cả issue đang giao cho chính bạn và chưa Done. Gợi ý: dùng currentUser().
  • Viết JQL lấy mọi Bug trong một project bạn chọn, sắp xếp theo priority giảm dần.
  • Viết JQL lấy issue được tạo từ đầu tuần này đến giờ. Gợi ý: created >= startOfWeek().
  • Viết JQL tìm issue có tiêu đề chứa từ "login" hoặc "đăng nhập". Dùng đúng toán tử contains.
  • Viết JQL lấy issue chưa gán cho ai (assignee trống) và đang ở To Do. Gợi ý: assignee IS EMPTY.
  • Lưu truy vấn số 1 thành filter có tên rõ ràng, rồi tạo một dashboard và gắn nó vào một gadget Pie Chart chia theo status.
  • Thử thách: viết một truy vấn cho "báo cáo SLA" — issue chưa đóng và được tạo cách đây hơn 7 ngày, sắp xếp issue cũ nhất lên đầu.
Sau khi làm xong, hãy tự hỏi: nếu sang tuần sau mở lại các filter này, con số có còn đúng không? Câu nào sẽ tự cập nhật, câu nào sẽ "đứng yên"? Trả lời được câu hỏi đó là bạn đã nắm được tinh thần của JQL trong reporting.

Tóm tắt

JQL là ngôn ngữ truy vấn issue của JIRA, được ghép từ field + operator + value, nối bằng AND/OR/NOT và sắp xếp bằng ORDER BY. Nó cho phép một BA hỏi JIRA chính xác điều mình cần thay vì click thủ công. Sức mạnh thật sự nằm ở các hàm như currentUser(), openSprints(), startOfWeek() — chúng biến truy vấn thành công cụ tự cập nhật theo thời gian thực.

Quan trọng hơn cả, JQL là khởi đầu của reporting: viết JQL → lưu thành filter (đặt tên, chia sẻ) → gắn filter vào gadget/dashboard hoặc export ra Excel. Chuỗi này biến dữ liệu thô thành báo cáo mà người ra quyết định đọc được. Tránh các lỗi cơ bản — quên ngoặc kép, nhầm = với ~, quên nhóm ngoặc đơn, dùng ngày cố định cho báo cáo định kỳ — và tận dụng autocomplete để học nhanh.

Ở các bài sau, chúng ta sẽ đào sâu hơn vào JQL cơ bản và nâng cao, cũng như các loại report tích hợp của JIRA. Nhưng nền tảng tư duy thì nằm cả ở đây: mỗi câu hỏi về dự án đều có thể trở thành một câu JQL, và mỗi câu JQL tốt đều có thể trở thành một báo cáo.