Archive
Combine multiple ROWS to CSV String… and vice-versa
There are times when you want to combine values from multiple rows of a single column into a CSV (Comma Separates Value) String.
Like combining multiple orders of each customer into one single row, or multiple Cities against each State as shown below.
It was a bit difficult to do in SQL Server 2000 and requires to create a customized function or a script.
But with SQL Server’s 2005 version, the new “PATH” mode with “FOR XML” provides us a way to get the desired output. Its a bit tricky but will do the needful, that’s why I’ve also added this post for my reference as well.
CREATE TABLE #tempCityState (State VARCHAR(5), City VARCHAR(50)) INSERT INTO #tempCityState SELECT 'CO', 'Denver' UNION SELECT 'CO', 'Teluride' UNION SELECT 'CO', 'Vail' UNION SELECT 'CO', 'Aspen' UNION SELECT 'CA', 'Los Angeles' UNION SELECT 'CA', 'Hanford' UNION SELECT 'CA', 'Fremont' UNION SELECT 'WA', 'Seattle' UNION SELECT 'WA', 'Redmond' UNION SELECT 'WA', 'Bellvue' SELECT * FROM #tempCityState
State City
CA Hanford
CA Fremont
CA Los Angeles
CO Denver
CO Aspen
CO Vail
CO Teluride
WA Seattle
WA Redmond
WA Bellvue
Using the “FOR XML PATH” syntax:
SELECT DISTINCT State, (SELECT SUBSTRING((SELECT ',' + City
FROM #tempCityState
WHERE State = t.State
FOR XML PATH('')),2,200000)) AS Cities
INTO #tempCityStateCSV
FROM #tempCityState t
-- OR --
SELECT DISTINCT State, (SELECT STUFF((SELECT ',' + City
FROM #tempCityState
WHERE State = t.State
FOR XML PATH('')),1,1,'')) AS Cities
FROM #tempCityState t
SELECT * FROM #tempCityStateCSV
State Cities
CA Hanford,Fremont,Los Angeles
CO Denver,Aspen,Vail,Teluride
WA Seattle,Redmond,Bellvue
Now, converting it back to multiple rows:
SELECT A.[State], Split.a.value('.', 'VARCHAR(100)') AS City
FROM (SELECT [State], CAST ('<M>' + REPLACE([Cities], ',', '</M><M>') + '</M>' AS XML) AS String
FROM #tempCityStateCSV) AS A
CROSS APPLY String.nodes ('/M') AS Split(a)
ORDER BY 1,2
State City CA Fremont CA Hanford CA Los Angeles CO Aspen CO Denver CO Teluride CO Vail WA Bellvue WA Redmond WA Seattle
Convert multiple Rows into a single column
Just replied an answer on a SQL forum (http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=148860), so thought to post this as well for future reference.
How will you output the following record set:
123456788 City 399.99
123456788 County 499.99
123456788 Flood 299.99
123456788 Hazzard 199.99
123456789 City 333.99
123456789 County 444.99
123456789 Flood 222.99
123456789 Hazzard 111.99
... into following pattern:
id Hazzard Flood City County
123456788 199.99 299.99 399.99 499.99
123456789 111.99 222.99 333.99 444.99
The following query will do it and convert the rows into columns:
select 123456788 as id, 'Hazzard' as des, 199.99 as val into #tempTable union select 123456788, 'Flood', 299.99 union select 123456788, 'City', 399.99 union select 123456788, 'County', 499.99 union select 123456789, 'Hazzard', 111.99 union select 123456789, 'Flood', 222.99 union select 123456789, 'City', 333.99 union select 123456789, 'County', 444.99 select * from #tempTable select a.id as id, a.val as Hazzard, b.val as Flood, c.val as City, d.val as County from #tempTable a,#tempTable b,#tempTable c, #tempTable d where a.id=b.id and b.id=c.id and c.id=d.id and a.des='Hazzard' and b.des='Flood' and c.des='City' and d.des='County' drop table #tempTable
The above select code is with a simple old style where clause with multiple tables joining. The code could be also converted to self-joins.




