Background
In traditional SQL is quite simple to achieve grouping and aggregating, however ESQL has some limitations that may not allow you to get the data in desired format.
In this example, we want to get table of test cases and its linked requirements. This information is available in custom report view SpiraTestEntities.R_RequirementTestCases and easily can be pulled out.
However, the view by default will list one row for each Requirements and Test Cases combination. In the image below we see 3 rows for the same requirement but with different test cases:
Ideally, we should be able to get one row for each item with aggregate results in a cell for those which has number of associated items:
Solution
Since ESQL version has only limited aggregation functionality, we can achieve exactly what we are after by modifying the XSLT template and aggregate the results that way.
So, the standard ESQL query will extract the information as described above, one row per record:
SELECT value R
FROM SpiraTestEntities.R_RequirementTestCases AS R
ORDER BY R.TEST_CASE_ID asc
Once the default template created, you'll be able to see the data as-is:
So, Test Case with ID = 2 has two Requirements with ID=4 and ID=30.
Lets modify our ESQL query first so to get requirements and test cases only, filtering by the current product and ordering results ascending:
SELECT
RTC.TEST_CASE_ID AS TC_ID,
RTC.TEST_CASE_NAME AS TC_NAME,
RTC.REQUIREMENT_ID AS RQ_NAME,
RTC.REQUIREMENT_NAME AS REQUIREMENT
FROM SpiraTestEntities.R_RequirementTestCases AS RTC
WHERE
RTC.PROJECT_ID = ${ProjectId}
ORDER BY RTC.TEST_CASE_ID asc
The result will be the same in terms of number of rows - duplicate items will be displayed for Test Cases (if there are more than one requirement associated).
Modifying XSLT
The reason for modification is to get only one row per test case with all associated requirements grouped.
For that, copy and paste the XSLT template in the corresponding Template text box under the custom query:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="groups" match="/RESULTS/ROW" use="ID" />
<xsl:template match="/RESULTS">
<table class="DataGrid">
<colgroup>
<col width="45px"/>
<col width="215px"/>
<col width="45px"/>
<col width="215px"/>
</colgroup>
<tr>
<th>TEST_CASE_ID</th>
<th>TEST_CASE_NAME</th>
<th>REQUIREMENT_ID</th>
<th>REQUIREMENT</th>
</tr>
<xsl:apply-templates select="ROW[generate-id() = generate-id(key('groups', ID)[1])]"/>
</table>
</xsl:template>
<xsl:template match="ROW">
<tr id="{ID}">
<td valign="top">
<table>
<tr>
<td valign="top" style="border: 0;">TC:<xsl:value-of select="ID"/></td>
</tr>
</table>
</td>
<td valign="top"><xsl:value-of select="NAME"/></td>
<td valign="top">
<xsl:if test="REQUIREMENT != ''">
<table>
<xsl:for-each select="key('groups', ID)">
<tr>
<td valign="top" style="border: 0;">RQ:<xsl:value-of select="REQUIREMENT_ID"/></td>
</tr>
</xsl:for-each>
</table>
<td valign="top">
<table>
<xsl:for-each select="key('groups', ID)">
<tr>
<td valign="top" style="border: 0;"><xsl:value-of select="REQUIREMENT"/></td>
</tr>
</xsl:for-each>
</table>
</td>
</xsl:if>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
Click Save button in both windows and now your custom report is ready for use.
Sample
The sample report can be ran from the Report Center and it should be similar to the example below: