I am trying to aggregate multiple rows into a single field (for multiple columns), grouped by a common ID (See below)
This is the what I have
ID CPT SVCDate Vendor
1 A3A 1/14/2023 A
2 DC6 1/23/2023 B
1 5WS 4/2/2023 A
3 DC6 5/3/2023 C
3 DC6 6/1/2023 C
I am trying to get:
ID CPT SVCDate Vendor
1 A3A,5WS 1/14/2023,4/2/2023 A,A
2 DC6 1/23/2023 B
3 DC6,DC6 5/3/2023,6/1/2023 C,C
My version of SQL doesn't support STRING_AGG()
Thanks a lot :)
SELECT ID,
CPT,
SVCDate,
Vendor,
STUFF((SELECT ', '+CPT
FROM Claims CD
WHERE CD.ID = D1.ID
FOR XML PATH ('')),1,2, ''),
STUFF((SELECT ', '+ CAST(SVCDate AS VARCHAR)
FROM Claims CD1
WHERE CD1.ID = D1.ID
FOR XML PATH ('')),1,2,''),
STUFF((SELECT ', '+Vendor
FROM Claims CD2
WHERE CD2.ID = D1.ID
FOR XML PATH ('')),1,2,'')
FROM Claims D1
GROUP BY ID,
CPT,
SVCDate,
Vendor
The above code is not working. I am expecting this result:
ID CPT SVCDate Vendor
1 A3A,5WS 1/14/2023,4/2/2023 A,A
2 DC6 1/23/2023 B
3 DC6,DC6 5/3/2023,6/1/2023 C,C
There is a way to do this without querying the table once for each column. You can just build an XML or JSON object of all the rows, and break them back out again using .nodes
or OPENJSON
.
Then re-aggregate it using FOR XML PATH('')
.
SELECT
c.ID,
STUFF((
SELECT ', ' + x2.r.value('(CPT/text())[1]', 'varchar(max)')
FROM x1.xmlData.nodes('r') x2(r)
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(max)'), 1, 2, '') AS CPT,
STUFF((
SELECT ', ' + x2.r.value('(SVCDate/text())[1]', 'varchar(max)')
FROM x1.xmlData.nodes('r') x2(r)
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(max)'), 1, 2, '') AS SVCDate,
STUFF((
SELECT ', ' + x2.r.value('(Vendor/text())[1]', 'varchar(max)')
FROM x1.xmlData.nodes('r') x2(r)
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(max)'), 1, 2, '') AS Vendor
FROM (
SELECT DISTINCT c.ID
FROM Claims c
) c1
CROSS APPLY (
SELECT CPT, SVCDate, Vendor
FROM Claims CD2
WHERE CD2.ID = D1.ID
FOR XML PATH('r')
) x1(xmlData);
Or with JSON
SELECT
c.ID,
STUFF((
SELECT ', ' + x2.CPT
FROM OPENJSON(x1.json)
WITH ( CPT varchar(max) ) x2
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(max)'), 1, 2, '') AS CPT,
STUFF((
SELECT ', ' + x2.SVCDate
FROM OPENJSON(x1.json)
WITH ( SVCDate varchar(max) ) x2
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(max)'), 1, 2, '') AS SVCDate,
STUFF((
SELECT ', ' + x2.Vendor
FROM OPENJSON(x1.json)
WITH ( Vendor varchar(max) ) x2
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(max)'), 1, 2, '') AS Vendor
FROM (
SELECT DISTINCT c.ID
FROM Claims c
) c1
CROSS APPLY (
SELECT CPT, SVCDate, Vendor
FROM Claims CD2
WHERE CD2.ID = D1.ID
FOR JSON PATH
) x1(json);