0

I have written the following SQL query:

SELECT DISTINCT i.IncidentReference Reference, s.Name Site, it.Description IncidentTypes
    , i.Description, FORMAT(i.CreatedOn,'d MMM yyyy', 'en-US' ) Logged 
FROM Incident i 
INNER JOIN TEST_USWM_TestAutomation.TEST_USWM.uvw_AvailaibleSites s ON i.SiteId = s.Id 
JOIN IncidentIncidentType iit ON i.Id = iit.IncidentId 
JOIN IncidentType it ON iit.IncidentTypeId = it.Id 
JOIN IncidentStatus ins ON i.IncidentStatusId = ins.Id 
WHERE s.Id = 1 /*:siteId */
AND ins.Name = 'Logged' 
AND i.CreatedOn BETWEEN DATEADD(DAY, -30, GETUTCDATE()) AND GETUTCDATE()

Which returns the following results:

Reference  Site  IncidentTypes                 Description    Logged
7032       0110  Refrigeration Outage          njfdgdf        25 Sep 2019
7095       0110  Fire/False Evacuation         testing        2 Oct 2019
7096       0110  Fire/False Evacuation         testing        2 Oct 2019
7097       0110  Fire/False Evacuation         test           2 Oct 2019
7097       0110  Flood                         test           2 Oct 2019
7097       0110  Gas Leak/Suspected Gas Leak   test           2 Oct 2019
7098       0110  Flood                         testing        2 Oct 2019
7168       0110  Fire/False Evacuation         test           7 Oct 2019
7330       0110  Refrigeration Outage          Test           15 Oct 2019

However, I am looking to combine all rows with the same Reference into one row. So for example, for Reference - 7097, I would want to see the column IncidentTypes look like - Gas Leak/Suspected Gas Leak, Fire/False Evacuation, Flood.

What would be the best way to do this?

EDIT: I have tried the query that @GMB posted below, but I am getting the error - The function 'STRING_AGG' may not have a WITHIN GROUP clause. This seems to be an issue with the version of SQL Server that I am using. Is there another way to get around this issue without upgrading the version ?

EDIT: Output for @Gordon Linoff's query -

9
  • Just a note, but you know that JOIN is the same as INNER JOIN? Commented Oct 22, 2019 at 9:16
  • 3
    Which dbms are you using? Commented Oct 22, 2019 at 9:17
  • Well you could use a groub by clause and appropriate aggregate functions for the columns (e.g. concatenate strings). What exactly you could use would depend on the database you're using though, because they all support different aggregate functions (there's a common set but most have their own additions). Commented Oct 22, 2019 at 9:20
  • There is no standard SQL syntax for this, so we need to know which database you're using, to see if that database has support for it. If you need generic cross-database code for this, you need to do it in Java code. Commented Oct 22, 2019 at 9:20
  • @Andreas: actually there is: listagg() is part of the SQL standard. Commented Oct 22, 2019 at 9:21

3 Answers 3

1

In older versions of SQL Server, you can use:

SELECT i.IncidentReference as Reference, 
       s.Name as Site, 
       STUFF( (SELECT it.Description + ','
               FROM IncidentType it
               WHERE iit.IncidentTypeId = it.Id 
               ORDER BY it.Description
               FOR XML PATH ('')
              ), 1, 2, ''
             ) as IncidentTypes,
      i.Description,
      FORMAT(i.CreatedOn,'d MMM yyyy', 'en-US' ) as Logged 
FROM Incident i JOIN
     TEST_USWM_TestAutomation.TEST_USWM.uvw_AvailaibleSites s 
     ON i.SiteId = s.Id JOIN
     IncidentStatus ins
     ON i.IncidentStatusId = ins.Id 
WHERE s.Id = 1 /*:siteId */ AND
      ins.Name = 'Logged' AND
      i.CreatedOn BETWEEN DATEADD(DAY, -30, GETUTCDATE()) AND GETUTCDATE();

I don't think the outer GROUP BY is needed.

Sign up to request clarification or add additional context in comments.

1 Comment

This query has ordered the values correctly, but has not combined them into one single row. Please see output above
1

In MySql you can use group_concat(it.Description) and then group by on reference

SELECT DISTINCT i.IncidentReference Reference, s.Name Site, group_concat(it.Description) IncidentTypes, 
i.Description, FORMAT(i.CreatedOn,'d MMM yyyy', 'en-US' ) Logged 
FROM Incident i 
INNER JOIN TEST_USWM_TestAutomation.TEST_USWM.uvw_AvailaibleSites s ON i.SiteId = s.Id 
JOIN IncidentIncidentType iit ON i.Id = iit.IncidentId 
JOIN IncidentType it ON iit.IncidentTypeId = it.Id 
JOIN IncidentStatus ins ON i.IncidentStatusId = ins.Id 
WHERE s.Id = 1 /*:siteId */
AND ins.Name = 'Logged' 
AND i.CreatedOn BETWEEN DATEADD(DAY, -30, GETUTCDATE()) AND GETUTCDATE() Group by reference;

Comments

0

You would need to use aggregation.

The use of GETUTCDATE() tend to indicate that you are using SQL Server. In this RDBMS, you can use function STRING_AGG() to aggregate the descriptions, as follows:

SELECT 
    i.IncidentReference Reference, 
    s.Name Site, 
    STRING_AGG(i.Description, ',') WITHIN GROUP(ORDER BY i.Description) IncidentTypes,
    i.Description,
    FORMAT(i.CreatedOn,'d MMM yyyy', 'en-US' ) Logged 
FROM 
    Incident i 
    JOIN TEST_USWM_TestAutomation.TEST_USWM.uvw_AvailaibleSites s ON i.SiteId = s.Id 
    JOIN IncidentIncidentType iit ON i.Id = iit.IncidentId 
    JOIN IncidentType it ON iit.IncidentTypeId = it.Id 
    JOIN IncidentStatus ins ON i.IncidentStatusId = ins.Id 
WHERE 
    s.Id = 1 /*:siteId */
    AND ins.Name = 'Logged' 
    AND i.CreatedOn BETWEEN DATEADD(DAY, -30, GETUTCDATE()) AND GETUTCDATE()
GROUP BY
    i.IncidentReference Reference, 
    s.Name Site, 
    i.Description,
    FORMAT(i.CreatedOn,'d MMM yyyy', 'en-US' ) Logged 

1 Comment

When I try this query I am getting the following error - The function 'STRING_AGG' may not have a WITHIN GROUP clause.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.