Files
gh-yebot-rad-cc-plugins-plu…/skills/jira-jql-patterns/SKILL.md
2025-11-30 09:08:00 +08:00

11 KiB

JQL Patterns Skill

Master JQL (Jira Query Language) query construction for advanced issue filtering and reporting.

Overview

JQL is Jira's powerful query language for finding issues. This skill provides patterns and templates for constructing effective queries using jira-cli.

Basic JQL Structure

field operator value [AND|OR field operator value]

Essential Field Reference

Issue Fields

Field Type Example
project Text project = PROJ
key Text key = PROJ-123
summary Text summary ~ "login"
description Text description ~ "error"
status Text status = "In Progress"
priority Text priority IN (High, Critical)
type Text type = Bug
labels List labels = urgent
component Text component = Backend
fixVersion Version fixVersion = "1.0"
resolution Text resolution = Fixed

People Fields

Field Type Example
assignee User assignee = currentUser()
reporter User reporter = "user@example.com"
creator User creator = currentUser()
watcher User watcher = currentUser()

Date Fields

Field Type Example
created Date created >= -7d
updated Date updated >= startOfWeek()
resolved Date resolved >= "2024-01-01"
duedate Date duedate <= now()

Agile Fields

Field Type Example
sprint Sprint sprint = 123
"Epic Link" Epic "Epic Link" = PROJ-100
"Story Points" Number "Story Points" > 5

Operators Reference

Equality

  • = - Equals
  • != - Not equals
  • IN - In list
  • NOT IN - Not in list

Comparison

  • > - Greater than
  • >= - Greater than or equal
  • < - Less than
  • <= - Less than or equal
  • ~ - Contains (case-insensitive)
  • !~ - Does not contain
  • IS - For checking null/empty
  • IS NOT - For checking not null/empty

Special

  • IS EMPTY - Field has no value
  • IS NOT EMPTY - Field has value
  • WAS - Historical value
  • CHANGED - Field was changed

JQL Functions

User Functions

assignee = currentUser()
reporter = currentUser()
watcher = currentUser()
assignee IN membersOf("developers")

Date Functions

created >= startOfDay()
created <= endOfDay()
created >= startOfWeek()
created >= startOfMonth()
created >= startOfYear()

updated >= startOfDay(-7)  # 7 days ago
duedate <= endOfWeek(1)     # End of next week

Sprint Functions

sprint IN openSprints()
sprint IN closedSprints()
sprint IN futureSprints()

Common Query Patterns

My Work Queries

Current work:

assignee = currentUser() AND status NOT IN (Done, Closed)

Recently completed:

assignee = currentUser() AND status = Done AND resolved >= -7d

Reported by me:

reporter = currentUser() AND status NOT IN (Done, Closed)

Watching:

watcher = currentUser() AND status NOT IN (Done, Closed)

Priority Queries

Critical and high priority open:

priority IN (Critical, High) AND status NOT IN (Done, Closed, Resolved)

Urgent bugs:

type = Bug AND priority = Critical AND status NOT IN (Done, Closed)

Prioritized backlog:

status = "To Do" AND priority IN (High, Medium) ORDER BY priority DESC

Time-Based Queries

Created today:

created >= startOfDay()

Updated this week:

updated >= startOfWeek()

Created in last 30 days:

created >= -30d

Overdue issues:

duedate < now() AND status NOT IN (Done, Closed)

Due this week:

duedate >= startOfWeek() AND duedate <= endOfWeek()

Stale issues (not updated in 90 days):

updated <= -90d AND status NOT IN (Done, Closed)

Team Queries

Unassigned issues:

assignee IS EMPTY AND status = "To Do"

Team workload:

assignee IN (user1@example.com, user2@example.com) AND status IN ("In Progress", "To Do")

Blocked issues:

status = Blocked OR labels = blocked

Issues needing review:

status = "In Review" AND assignee IS NOT EMPTY

Sprint Queries

Current sprint:

sprint IN openSprints()

Current sprint for project:

project = PROJ AND sprint IN openSprints()

Specific sprint:

sprint = 123

Issues without sprint:

type IN (Story, Bug, Task) AND sprint IS EMPTY

Incomplete sprint items:

sprint = 123 AND status NOT IN (Done, Closed)

Epic Queries

All issues in epic:

"Epic Link" = PROJ-100

Completed epic issues:

"Epic Link" = PROJ-100 AND status = Done

Issues without epic:

type = Story AND "Epic Link" IS EMPTY

Bug Tracking Queries

Open bugs:

type = Bug AND status NOT IN (Done, Closed, "Won't Fix")

Critical production bugs:

type = Bug AND priority = Critical AND labels = production AND status NOT IN (Done, Closed)

Bugs by component:

type = Bug AND component = Backend AND status NOT IN (Done, Closed)

Recently fixed bugs:

type = Bug AND status = Done AND resolved >= -7d

Regression bugs:

type = Bug AND labels = regression AND status NOT IN (Done, Closed)

Story Queries

Ready for development:

type = Story AND status = "To Do" AND "Story Points" IS NOT EMPTY

Unestimated stories:

type = Story AND "Story Points" IS EMPTY AND status = "To Do"

Large stories (need breakdown):

type = Story AND "Story Points" >= 13

Component Queries

Frontend issues:

component = Frontend AND status NOT IN (Done, Closed)

Backend bugs:

component = Backend AND type = Bug AND status NOT IN (Done, Closed)

Issues without component:

component IS EMPTY AND type IN (Story, Bug, Task)

Label Queries

Technical debt:

labels = tech-debt AND status NOT IN (Done, Closed)

Multiple labels:

labels IN (urgent, critical) AND status NOT IN (Done, Closed)

Issues without labels:

labels IS EMPTY AND type IN (Story, Bug)

Advanced Patterns

Complex Logic with Parentheses

project = PROJ AND
(priority = Critical OR labels = urgent) AND
status NOT IN (Done, Closed)
ORDER BY created DESC

Historical Queries

Issues that were in progress:

status WAS "In Progress" DURING (-7d, now())

Issues that changed priority:

priority CHANGED DURING (-30d, now())

Issues moved to done this week:

status CHANGED TO Done DURING (startOfWeek(), now())

Negative Queries

Not assigned to specific team:

assignee NOT IN membersOf("qa-team")

Exclude certain statuses:

status NOT IN (Done, Closed, "Won't Fix", Duplicate)

Not labeled:

labels IS EMPTY

Multi-Project Queries

Across projects:

project IN (PROJ1, PROJ2, PROJ3) AND assignee = currentUser()

All projects bugs:

type = Bug AND priority = Critical AND status NOT IN (Done, Closed)

Sorting Patterns

Single Sort

ORDER BY priority DESC
ORDER BY created ASC
ORDER BY updated DESC
ORDER BY duedate ASC

Multiple Sort

ORDER BY priority DESC, created ASC
ORDER BY status ASC, priority DESC, updated DESC
ORDER BY duedate ASC, priority DESC

Using with jira-cli

Basic Query

jira issue list --jql "assignee = currentUser() AND status = 'In Progress'"

Multi-line for Readability

jira issue list --jql "\
  project = PROJ AND \
  status IN ('In Progress', 'In Review') AND \
  assignee = currentUser() AND \
  created >= -7d \
  ORDER BY priority DESC"

With Output Formats

# Human readable
jira issue list --jql "..." --plain

# JSON for parsing
jira issue list --jql "..." --raw

# CSV for export
jira issue list --jql "..." --csv

Report Patterns

Sprint Velocity

sprint = 123 AND status = Done

Sum story points from results.

Bug Trend

type = Bug AND created >= -30d
type = Bug AND resolved >= -30d

Compare created vs resolved.

Team Performance

assignee IN membersOf("dev-team") AND
status = Done AND
resolved >= startOfWeek()

Epic Progress

"Epic Link" = PROJ-100
"Epic Link" = PROJ-100 AND status = Done

Calculate percentage complete.

Technical Debt Tracking

labels = tech-debt AND
status NOT IN (Done, Closed) AND
created <= -90d
ORDER BY priority DESC, created ASC

Query Optimization Tips

1. Narrow by Project First

Slow:

status = "In Progress"

Fast:

project = PROJ AND status = "In Progress"

2. Use Specific Operators

Slow:

summary ~ ".*login.*"

Fast:

summary ~ "login"

3. Limit Results

jira issue list --jql "..." --limit 100

4. Use IS EMPTY Instead of Negation

Slower:

assignee != null

Faster:

assignee IS NOT EMPTY

Common Mistakes

Mistake 1: Missing Quotes

Wrong:

status = In Progress

Correct:

status = "In Progress"

Mistake 2: Wrong Function

Wrong:

assignee = me

Correct:

assignee = currentUser()

Mistake 3: Wrong Field Name

Wrong:

epic = PROJ-100

Correct:

"Epic Link" = PROJ-100

Mistake 4: Wrong Date Format

Wrong:

created > 7d

Correct:

created >= -7d

Debugging Queries

Step 1: Simplify

Start with basic query:

project = PROJ

Step 2: Add Conditions Incrementally

project = PROJ AND status = "In Progress"
project = PROJ AND status = "In Progress" AND assignee = currentUser()

Step 3: Test Each Addition

Run query after each change to identify issues.

Step 4: Check Field Names

Verify custom field names in Jira UI.

Step 5: Use --debug

jira issue list --jql "..." --debug

Saving Common Queries

Shell Aliases

alias jira-my-work='jira issue list --jql "assignee = currentUser() AND status NOT IN (Done, Closed)" --plain'
alias jira-urgent='jira issue list --jql "priority IN (Critical, High) AND status NOT IN (Done, Closed)" --plain'
alias jira-sprint='jira issue list --jql "sprint IN openSprints()" --plain'

Script Functions

# Add to ~/.bashrc or ~/.zshrc
jira-find() {
  local query="$1"
  jira issue list --jql "summary ~ \"$query\" OR description ~ \"$query\"" --plain
}

jira-my-bugs() {
  jira issue list --jql "assignee = currentUser() AND type = Bug AND status NOT IN (Done, Closed)" --plain
}

jira-overdue() {
  jira issue list --jql "duedate < now() AND status NOT IN (Done, Closed)" --plain
}

When to Use This Skill

  • User needs complex issue filtering
  • Generating reports or metrics
  • Finding issues across projects
  • Historical queries
  • Performance optimization needed
  • Combining multiple criteria

Next Steps

After mastering JQL:

  1. Create saved queries for common needs
  2. Integrate queries into automation scripts
  3. Build dashboards based on queries
  4. Share query templates with team
  5. Document organization-specific patterns