How to convert several rows into a CSV string
Scenario I recently posted just about the opposite (see INNER JOIN with a comma separated values CSV field ) and now I want to show how to create a CSV list when you have several rows to merge, grouping by some criteria. Let's suppose you have a set of data such as:
F1 F2 Item ----------------- 1 4 A 1 4 B 3 2 A 3 3 C 5 1 B 5 4 A 5 4 E 5 4 F 6 1 E 6 1 WAnd you need to generate something like:
F1 F2 ItemsList ----------------- 1 4 A, B 3 2 A 3 3 C 5 1 B 5 4 A, E, F 6 1 E, WSolution This procedure is based on the information I found on Converting Multiple Rows into a CSV String (Set Based Method) but tuned to be able to group by a set of fields, not only one:
IF NOT OBJECT_ID('tempdb..#Source') IS NULL
DROP TABLE #Source
IF NOT OBJECT_ID('tempdb..#t') IS NULL
DROP TABLE #t
SELECT 1 F1, 4 F2, 'A' Item INTO #Source
UNION ALL SELECT 1, 4, 'B'
UNION ALL SELECT 3, 2, 'A'
UNION ALL SELECT 3, 3, 'C'
UNION ALL SELECT 5, 1, 'B'
UNION ALL SELECT 5, 4, 'A'
UNION ALL SELECT 5, 4, 'E'
UNION ALL SELECT 5, 4, 'F'
UNION ALL SELECT 6, 1, 'E'
UNION ALL SELECT 6, 1, 'W'
CREATE TABLE #t (
F1 int not null,
F2 int not null,
Item varchar(7) not null,
ItemsList varchar(8000)
)
INSERT INTO #t (F1, F2, Item)
SELECT TOP (100) PERCENT F1, F2, Item
FROM #Source
ORDER BY F1, F2, Item
DECLARE
@List varchar(8000),
@F1_Last int,
@F2_Last int
SELECT
@List = '',
@F1_Last = -1,
@F2_Last = -1
UPDATE #t
SET
@List = ItemsList =
CASE
WHEN (@F1_Last <> F1) OR
(@F2_Last <> F2)
THEN Item
ELSE @List + ', ' + Item
END,
@F1_Last = F1,
@F2_Last = F2
SELECT TOP (100) PERCENT F1, F2,
CASE
WHEN LEN(MAX(ItemsList)) > 512
THEN CONVERT(varchar(512), LEFT(MAX(ItemsList), 509) + '...')
ELSE CONVERT(varchar(512), MAX(ItemsList))
END AS ItemsList
FROM #t
GROUP BY F1, F2
ORDER BY F1, F2
GO



