Use case: Comments and worklogs on one row
A flat export puts all of a work item’s comments in one column, with internal notes marked
[internal]. This SQL export keeps one row per work
item but splits them: internal notes in one column, replies to the customer in another,
and every worklog entry in a third, with the total hours beside it.
It suits a Jira Service Management audit or clean-up: run it once a year for the year just finished, and each ticket’s full story arrives as one Excel row.
Set up the export
Section titled “Set up the export”-
Create an export and choose its work items, for example a service project’s tickets created last year:
project = HELP AND created >= startOfYear(-1) AND created < startOfYear() ORDER BY keystartOfYear(-1)always means the start of last year, so the same export covers the year just finished every time it runs. For an earlier year, use dates:created >= 2024-01-01 AND created < 2025-01-01. -
Add the Key, Summary, Description, Assignee, Reporter, Comment and Log Work fields. Comment fills the
commentstable and Log Work theworklogstable: without them those columns are empty. -
Under Output, choose SQL query and paste the query below.
-
Choose Run on sample to check the result, then Save.
You do not need Export historical changes for this report.
The query
Section titled “The query”WITH comment_cols AS ( SELECT c.work_item_id, string_agg( coalesce(u.displayName, 'Unknown') || ', ' || strftime(c.created, '%Y-%m-%d %H:%M') || ': ' || c.body, chr(10) ORDER BY c.created ) FILTER (WHERE c.jsd_public = false) AS internal_comments, string_agg( coalesce(u.displayName, 'Unknown') || ', ' || strftime(c.created, '%Y-%m-%d %H:%M') || ': ' || c.body, chr(10) ORDER BY c.created ) FILTER (WHERE c.jsd_public) AS public_comments FROM comments c LEFT JOIN users u ON u.id = c.author_id GROUP BY c.work_item_id),worklog_cols AS ( SELECT w.work_item_id, string_agg( coalesce(u.displayName, 'Unknown') || ', ' || strftime(w.started, '%Y-%m-%d') || ', ' || round(w.time_spent_seconds / 3600.0, 2) || 'h' || coalesce(': ' || w.comment, ''), chr(10) ORDER BY w.started ) AS worklogs, round(sum(w.time_spent_seconds) / 3600.0, 2) AS hours_logged FROM worklogs w LEFT JOIN users u ON u.id = w.author_id GROUP BY w.work_item_id)SELECT wi.key AS "Key", wi.summary AS "Summary", wi.description AS "Description", wi.assignee AS "Assignee", wi.reporter AS "Reporter", c.internal_comments AS "Internal comments", c.public_comments AS "Public comments", wl.worklogs AS "Work logged", wl.hours_logged AS "Total hours"FROM work_items_display wi LEFT JOIN comment_cols c ON c.work_item_id = wi.id LEFT JOIN worklog_cols wl ON wl.work_item_id = wi.idORDER BY wi.keyHow it works:
comment_colsturns thecommentstable, one row per comment, into one row per work item.string_aggjoins its comments into a single text, oldest first and one per line, each with its author and time.FILTERpicks which comments go into each column:jsd_publicisfalsefor an internal note andtruefor a reply the customer can see.worklog_colsdoes the same forworklogs: one line per entry with who logged it, the day, the hours and the worklog comment, plus the total in hours. An entry without a comment has no trailing colon.- The final
SELECTtakes each work item fromwork_items_display, which has names rather than ids (an assignee’s name, not their account id), and joins the two summaries to it.
Example result
Section titled “Example result”The names and text below are made up, to show the shape of the result. Each line inside a cell is a separate line in Excel.
| Key | Summary | Assignee | Reporter | Internal comments | Public comments | Work logged | Total hours |
|---|---|---|---|---|---|---|---|
| HELP-101 | Printer offline on floor 3 | Alex Morgan | Jamie Fox | Alex Morgan, 2025-03-03 10:15: Driver needs updating | Alex Morgan, 2025-03-03 09:40: Thanks, looking into it Alex Morgan, 2025-03-04 14:05: Fixed, can you confirm? Jamie Fox, 2025-03-04 15:00: Works now, thanks |
Alex Morgan, 2025-03-03, 1.5h: Updated the driver Alex Morgan, 2025-03-04, 0.5h |
2 |
| HELP-102 | VPN drops every hour | Sam Lee | Riley Chen | Sam Lee, 2025-04-01 10:30: Escalated to the network team | Sam Lee, 2025-04-01, 1.0h: Call with the user | 1 | |
| HELP-103 | New laptop request | Jamie Fox |
A work item with no comments or no time logged still has its row, with those cells empty.
Adjusting the query
Section titled “Adjusting the query”- More fields. Any field you add to the export is a column of
work_items_display, named by its field id, such aswi.priorityorwi.customfield_10010. Service management fields such as Urgency, Impact or Organizations are custom fields: the field picker shows each one’s id beside its name. Add them to the finalSELECT. - Projects other than service management. Outside Jira Service Management,
jsd_publicis empty (NULL) and both comment columns stay empty. For all comments in one column, replace the twostring_agg(...) FILTER (...)expressions with one, without theFILTER. - Comment text only. To leave out the author and time, use
string_agg(c.body, chr(10) ORDER BY c.created). - A different separator. Replace
chr(10)(a new line) with, for example,' | 'to keep each cell on one line. - Hours and minutes as Jira shows them. In
worklog_cols, replaceround(w.time_spent_seconds / 3600.0, 2) || 'h'withformat('{}h {}m', w.time_spent_seconds // 3600, (w.time_spent_seconds % 3600) // 60).
An Excel cell holds at most 32,767 characters, so a ticket with a very long comment thread may not fit in one cell. If that happens, use the comment text only, or CSV.
Times are in the export owner’s time zone; see Dates and times.
Or ask an AI agent
Section titled “Or ask an AI agent”You can skip the steps above and ask an agent instead: the Rovo agent, or an AI assistant such as Claude connected through MCP. It uses the app’s tools to create the export, write and run the query, and schedule it. You see the result before anything is saved.
Copy this prompt, and change the project key HELP to yours:
Create a report called "Tickets with comments and worklogs" for project HELP, withone row per work item. Read work items matching the JQL"project = HELP AND created >= startOfYear(-1) AND created < startOfYear() ORDER BY key",with the Key, Summary, Description, Assignee, Reporter, Comment and Log Work fields.For each work item show the key, summary, description, assignee and reporter names,then three columns: internal comments, public comments (replies the customer can see),and work logged. In each, list that work item's entries oldest first, one per line,with the author's name and date. For work logged also show the hours and the worklogcomment, and add a column with the total hours logged.
Show me the result on my data first.
Once I confirm, save it as a SQL export and schedule it to run every year on 2 Januaryat 8:00, emailing it to me as an Excel (XLSX) file.The agent works through it in steps and asks you to confirm each one that saves something: the export, the SQL query and the schedule. Its query may differ from the one above, so check it shows the columns you expect before you confirm. For screenshots of each step, see the same flow in Last week’s worklogs.