JQL Cheat Sheet: 67 Queries Tested on Jira Cloud (2026)

On this page
  1. How a JQL query is built
  2. Your own work
  3. Status and resolution
  4. Dates
  5. Text
  6. People and teams
  7. Sprints and releases
  8. Epics, parents, subtasks and links
  9. History: WAS and CHANGED
  10. Other fields, spaces and sorting
  11. All 17 operators
  12. The renamed functions: which work today
  13. Seven traps, tested
  14. Build it without typing
  15. How we tested

A team lead wants to see what everyone else is working on and types assignee != currentUser(). The list looks right. It is short by 56 work items: every one that nobody is assigned to. JQL reads != as “has a value, and the value is not this”, so the empty ones never make it in.

That is the kind of thing this cheat sheet is for. All 67 queries on this page were run on a live Jira Cloud site on 13 November 2026, a test site with 162 work items in 12 spaces, with Jira’s own strict check (/rest/api/3/jql/parse?validation=strict) and a count of what each returned. None of them failed. The traps further down come with the numbers that show them.

Short answer: a JQL query is clauses of field, operator, value, joined by AND and OR and sorted with ORDER BY: project = PAY AND statusCategory != Done ORDER BY priority DESC. Use statusCategory for “done or not”, -7d and startOfWeek() for dates, ~ for text, openSprints() for the running sprint. AND is read before OR, != skips empty fields, and text search never matches part of a word.

How a JQL query is built

A query is one or more clauses. Each clause names a field, an operator and a value or a function that returns values. Keywords join the clauses, brackets group them, and ORDER BY comes last.

Diagram of the JQL query project = PAY AND (assignee = currentUser() OR assignee is EMPTY) ORDER BY priority DESC, updated DESC, split into its parts. Field: what to look at, such as project, status, due, sprint or Team. Operator: how to compare, such as = != > < ~ in is was changed, 17 in all. Value or function: PAY, In Review, -7d, currentUser(), openSprints(), EMPTY. Keyword: AND, OR and NOT join or flip clauses, ORDER BY sorts. Below: AND is read before OR, so statusCategory = Done AND (priority = High OR priority = Highest) found 4 work items and the same query without brackets found 13. Sources: Atlassian JQL reference pages and our Jira Cloud test site.

Three rules save most of the debugging:

  1. Quote values with spaces or special characters: status = "In Review", labels = "select".
  2. AND binds tighter than OR. statusCategory = Done AND priority = High OR priority = Highest returned 13 items on our site; with brackets around the two priorities, 4.
  3. A query needs at least one condition when an app or a script runs it through the REST API. order by key on its own came back as Unbounded JQL queries are not allowed here. Please add a search restriction to your query.

Your own work

You wantJQL
My open work, most urgent firstassignee = currentUser() AND statusCategory != Done ORDER BY priority DESC, updated DESC
What I reported in the last 30 daysreporter = currentUser() AND created >= -30d
What I watch and is still openwatcher = currentUser() AND statusCategory != Done
Everything I watchissue in watchedIssues()
What I opened recentlyissue in issueHistory() ORDER BY lastViewed DESC
Viewed in the last weeklastViewed >= -7d
Mine or nobody’s in one spaceassignee in (currentUser(), EMPTY) AND project = PAY

issueHistory() returns the work items you opened most recently, up to 50 of them, where Jira’s recent menu shows 5 (Atlassian’s functions page).

Status and resolution

You wantJQL
Not startedstatusCategory = "To Do"
Being worked onstatusCategory = "In Progress"
Not finished, whatever the workflowstatusCategory != Done
Exact statusesstatus in ("In Progress", "In Review")
Not in two statusesstatus not in (Done, Closed)
No resolution setresolution = Unresolved
Done but nobody set a resolutionresolution = Unresolved AND statusCategory = Done
Resolved but reopenedresolution is not EMPTY AND statusCategory != Done

Prefer statusCategory to a list of statuses. Every status belongs to To Do, In Progress or Done, so the query keeps working when someone adds “In Review” or “Released” to the workflow.

resolution = Unresolved is not the same as “not done”. On our site it matched 137 items, statusCategory != Done matched 131, and the difference was six items sitting in a Done status (one of them “Released”) with no resolution, because their workflow never sets one. Reports and gadgets that count “unresolved” count those six as open work forever.

Dates

You wantJQL
Created todaycreated >= startOfDay()
Created this weekcreated >= startOfWeek()
Created in the last 7 dayscreated >= -7d
Open and untouched for a monthupdated <= -30d AND statusCategory != Done
Overduedue < now() AND statusCategory != Done
Due this weekdue >= startOfDay() AND due <= endOfWeek()
Open with no due dateduedate is EMPTY AND statusCategory != Done
Resolved last monthresolved >= startOfMonth(-1) AND resolved < startOfMonth()
A fixed quartercreated >= "2026-01-01" AND created < "2026-04-01"

Dates go year first. created > "11/01/2026" failed with Date value '11/01/2026' for field 'created' is invalid. Valid formats include: 'yyyy/MM/dd HH:mm', 'yyyy-MM-dd HH:mm', 'yyyy/MM/dd', 'yyyy-MM-dd', or a period format e.g. '-5d', '4w 2d'. The full story of relative dates, time zones and the startOf and endOf functions is in JQL dates.

Text

You wantJQL
A word in the summarysummary ~ "payment"
An exact phrasesummary ~ "\"duplicate charge\""
Words that start with refundsummary ~ "refund*"
Summary, description and commentstext ~ "timeout"
Only in commentscomment ~ "rollback"
No description at alldescription is EMPTY
Without a wordsummary !~ "test"

Text search works on whole words, after Jira cuts them to a root form (“customize” is stored as “custom”, Atlassian’s text search page explains). What that means in practice, from our tests:

  • summary ~ "pay" found nothing, though one summary says “retry failed payment”. "pay*" found it. A star at the start, "*etry", found nothing.
  • ? stands for one letter: "pay?ent" found the payment item.
  • Common English words are left out of the index. summary ~ "the retry" matched the same three items as "retry". Atlassian’s own example: a search for “VSX will crash” also finds “VSX will not crash”, because “will” and “not” are on the list.
  • A phrase needs inner quotes escaped with a backslash, as in the table.

People and teams

You wantJQL
Unassigned and open in one spaceassignee is EMPTY AND project = PAY AND statusCategory != Done
Someone in a groupassignee in membersOf("jira-users-simplify-demo")
I reported it, someone else has itreporter = currentUser() AND assignee != currentUser()
Reassigned this weekassignee changed AFTER -7d
I voted for itvoter = currentUser()
Most votes firstvotes > 0 ORDER BY votes DESC

Put your own group name in membersOf(). A group that does not exist is an error, not an empty result. For the difference between the reporter and the assignee, and why reporter != assignee does not do what it reads like, see Jira reporter vs assignee.

Sprints and releases

You wantJQL
In a running sprintsprint in openSprints()
Planned for a later sprintsprint in futureSprints()
Carried over into the running sprintsprint in closedSprints() AND sprint in openSprints()
Open work in no sprintsprint is EMPTY AND statusCategory != Done AND project = PAY
In versions not released yetfixVersion in unreleasedVersions()
In the next release of one spacefixVersion = earliestUnreleasedVersion(PAY)
Done but in no releasefixVersion is EMPTY AND resolution = Done

openSprints() covers every running sprint the site has, so add project = PAY when you want one team. More sprint queries, and what counts as “done” at the end of a sprint, are in our Jira sprints guide.

You wantJQL
Children of one epicparent = PAY-1
Open epicstype = Epic AND statusCategory != Done
All subtaskshierarchyLevel = -1
Subtask types, or the standard onesissuetype in subTaskIssueTypes() / issuetype in standardIssueTypes()
Linked to one work itemissue in linkedIssues("PAY-1")
Blocking one work itemissue in linkedIssues("PAY-1", "is blocked by")
Blocked and still openissueLinkType = "is blocked by" AND statusCategory != Done

hierarchyLevel uses numbers: 1 for epics (the parent level), 0 for stories and tasks, -1 for subtasks. Levels above epic made in Plans are not covered. Grandchildren, "Epic Link" and why some link queries return nothing are in JQL for parents, epics and linked issues.

History: WAS and CHANGED

You wantJQL
Was in progress before this weekstatus WAS "In Progress" BEFORE startOfWeek()
Moved back to To Do in two weeksstatus CHANGED FROM "In Progress" TO "To Do" AFTER -14d
Finished last monthstatus CHANGED TO Done DURING (startOfMonth(-1), endOfMonth(-1))
Ever assigned to meassignee WAS currentUser()
Priority changed this weekpriority CHANGED AFTER -7d

WAS and CHANGED read the history. Atlassian lists six fields for WAS: assignee, fix version, priority, reporter, resolution and status. labels WAS payments failed on our site: Jira answered that history searches do not support the labels field. The predicates (AFTER, BEFORE, DURING, ON, BY, FROM, TO) are covered in JQL WAS and CHANGED.

Other fields, spaces and sorting

Labels, components and other fields

You wantJQL
No labelslabels is EMPTY
Either of two labelslabels in (payments, checkout)
Without a label, unlabelled includedlabels not in (payments) OR labels is EMPTY
No component in one spacecomponent is EMPTY AND project = PAY
With attachmentsattachments is not EMPTY
Stories nobody estimated"Story point estimate" is EMPTY AND type = Story AND statusCategory != Done

Fields with spaces in their names go in quotes. On a company-managed space the field is often "Story Points"; on a team-managed one, "Story point estimate". Both exist on our site. A field can also be named by its ID, cf[10016].

Spaces and permissions

You wantJQL
Spaces I leadproject in projectsLeadByUser()
Spaces where I hold a roleproject in projectsWhereUserHasRole("Administrators")

Sorting

You wantJQL
Board orderproject = PAY ORDER BY Rank ASC
Priority, then oldest firstproject = PAY ORDER BY priority DESC, created ASC

ORDER BY takes several fields, each with ASC or DESC. It changes the order only, not which items match.

All 17 operators

OperatorMeaningExample
=is exactlystatus = Done
!=has a value, and not this onepriority != Low
> >= < <=after or before, more or lessdue < now()
INany of a liststatus in ("To Do", "In Progress")
NOT INnone of a list, empty excludedlabels not in (payments)
~contains wordssummary ~ "refund*"
!~does not contain wordssummary !~ "test"
ISis emptyassignee is EMPTY
IS NOTis not emptyattachments is not EMPTY
WAShad this value at some pointassignee WAS currentUser()
WAS INhad any of these valuesstatus WAS IN ("In Review", QA)
WAS NOTnever had this value (in a period)status WAS NOT Done BEFORE -7d
WAS NOT INnever had any of thesestatus WAS NOT IN (Done, Closed)
CHANGEDthe value changedpriority CHANGED AFTER -7d

IS and IS NOT only take EMPTY (or its synonym NULL). ~ and !~ only work on text fields.

The renamed functions: which work today

In 2026 Atlassian started calling issues “work items” and projects “spaces”. The JQL reference now lists new names, with a warning on the keywords page that “some JQL entries using the new terms may not work yet”. We ran each name exactly as the reference prints it on our site on 13 November 2026.

Old nameNew name in the docsNew name works?
issueHistory()workItemHistory()Yes
watchedIssues()watchedWorkItems()Yes
votedIssues()votedWorkItems()Yes
projectsLeadByUser()spacesLeadByUser()Yes
projectsWhereUserHasRole()spacesWhereUserHasRole()Yes
projectsWhereUserHasPermission()spacesWhereUserHasPermission()Yes
standardIssueTypes()standardWorkTypes()Yes
subTaskIssueTypes()subtaskWorkTypes()Yes
issuesWithRemoteLinksByGlobalId()workItemsWithRemoteLinksByGlobalId()Yes
issuekeyworkItemKeyYes
issueLinkTypeworkItemLinkTypeYes
projectTypespaceTypeYes
projectspaceJiraYes
linkedIssues()linkedWorkItems()No: Unable to find JQL function 'linkedWorkItems(SPR-10)'.
parentProjectparentSpaceNo: Field 'parentSpace' does not exist or you do not have permission to view it.

The obvious guess fails too: space = SPR returned Field 'space' does not exist or you do not have permission to view it. The old names all still work, so saved filters, boards and Automation rules are safe. For new queries, keep the old names until the new ones work everywhere.

Seven traps, tested

Table titled Seven JQL traps, tested on Jira Cloud, on our test site with 162 work items. assignee != currentUser() found 86 items and left out the 56 unassigned; add OR assignee is EMPTY for 142. Done AND High OR Highest found 13 items because AND is read first; with brackets, 4. resolution = Unresolved found 137 items, 6 of them in a Done status with no resolution; use statusCategory != Done for not finished. reporter != assignee returned all 106 assigned items, also the 10 where reporter and assignee are the same person; JQL cannot compare two fields. summary ~ pay found 0 items though payment is in a summary; pay* found 1. created > 11/01/2026 is an error; write 2026-11-01, year first. space = PAY is an error, field space does not exist; write project = PAY or spaceJira = PAY.
  1. != and NOT IN skip empty fields. 86 instead of 142 in our test. Add OR field is EMPTY.
  2. AND before OR. 13 instead of 4. Put brackets around every OR.
  3. Unresolved is not “not done”. Six done items had no resolution. Use statusCategory.
  4. No field-to-field comparison. reporter != assignee returned all 106 assigned items, including the 10 where both were the same person. reporter = assignee returned 0.
  5. No part words. "pay" missed “payment”. Use "pay*".
  6. Dates are year first. US-style dates are an error.
  7. Reserved words need quotes. labels = select failed with Error in the JQL Query: 'select' is a reserved JQL word. You must surround it in quotation marks. JQL reserves 195 words, among them select, order, limit, user, date and empty. Characters such as @ or brackets inside a text search go in quotes too, and a bracket needs two backslashes: summary ~ "\\(text".

Build it without typing

If you would rather click than type, our free JQL builder writes a query from a form and explains one you paste, clause by clause, with the traps above flagged. It runs in your browser and sends nothing anywhere.

Inside Jira, our app JQL Blocks does the same with blocks: AND, OR, groups and NOT, the JQL written beside them, and sprint start and end dates as real Jira fields that plain JQL does not have.

How we tested

  • Site: a Jira Cloud test site on the Standard plan, 162 work items in 12 spaces (software, service and business), on 13 November 2026.
  • Syntax: every query on this page through POST /rest/api/3/jql/parse?validation=strict, which also checks that fields, values and functions exist. 67 of 67 passed.
  • Results: each query counted with POST /rest/api/3/search/approximate-count; the traps were then checked one by one in the search results.
  • Reference: Atlassian’s JQL fields, operators, functions, keywords, advanced search and text search pages, read on the same day.

Space keys, group names and work item keys such as PAY-1 are from our site. Replace them with yours.

Frequently asked questions

How do I write a JQL query?

Open Jira search, switch to JQL, and write clauses of the form field, operator, value: project = PAY, status = "In Review", due < now(). Join clauses with AND or OR, group them in brackets, and end with ORDER BY to sort, for example project = PAY AND statusCategory != Done ORDER BY priority DESC.

Is JQL the same as SQL?

No. JQL looks like a SQL WHERE clause, but there is no SELECT, no JOIN and no GROUP BY, and you cannot compare two fields with each other: reporter != assignee is read as "reporter is not a person called assignee". JQL only picks work items and sorts them; Jira decides which columns you see.

What does statusCategory mean in JQL?

Every status belongs to one of three categories: To Do, In Progress and Done. statusCategory != Done finds unfinished work whatever your workflow calls its statuses, so the query keeps working when someone adds a status such as In Review or Released.

Why does != hide work items with an empty field?

In JQL, != and NOT IN only match work items where the field has a value. On our test site assignee != currentUser() returned 86 items and left out 56 unassigned ones. Add OR assignee is EMPTY to keep them; the same goes for labels, components and versions.

How do I search for part of a word in JQL?

You cannot match the middle of a word. Text search works on whole words, so summary ~ "pay" did not find "payment" in our test. Put * at the end, summary ~ "pay*", or ? for a single letter. A * at the start, as in "*etry", returned nothing.

Do the new names in the Jira docs work in JQL?

Most do. In November 2026 workItemHistory(), watchedWorkItems(), spacesLeadByUser(), workItemKey and workItemLinkType all worked. linkedWorkItems() and parentSpace failed with errors, and space = KEY failed too, so keep linkedIssues(), parentProject and project.

Keep reading