I’m looking for a way to combine different rows into a single row with columns.
Let’s take this example table:
destinationIP sourceDataCenter latency ------------- ---------------- ------- 1.1.1.1 Data Center A 10ms 1.1.1.1 Data Center B 12ms 1.1.1.1 Data Center C 5ms 1.1.1.2 Data Center A 50ms
Desired output:
destinationIP Data Center A Data Center B Data Center C ------------- ------------- ------------- ------------- 1.1.1.1 10ms 12ms 5ms 1.1.1.2 50ms
Please note that Data centers are not necessarily these three, they can be N
different data centers that I will not know in advance.
Advertisement
Answer
With a known set of sourceDataCenter
values, you can just use a simple PIVOT
operator:
DECLARE @x TABLE ( destinationIP varchar(15), sourceDataCenter varchar(255), latency varchar(32) ); INSERT @x VALUES ('1.1.1.1','Data Center A','10ms'), ('1.1.1.1','Data Center B','12ms'), ('1.1.1.1','Data Center C','5ms'), ('1.1.1.2','Data Center A','50ms'); SELECT destinationIP, [Data Center A], [Data Center B], [Data Center C] FROM @x AS x PIVOT ( MAX(latency) FOR sourceDataCenter IN ( [Data Center A],[Data Center B],[Data Center C] ) ) AS p ORDER BY destinationIP;
If you don’t know the names of the data centers in advance, you need to use dynamic SQL to generate an equivalent query, first by getting the distinct list of values, and then adding those into the two relevant spots in the query:
USE tempdb; GO CREATE TABLE dbo.YourTable ( destinationIP varchar(15), sourceDataCenter varchar(255), latency varchar(32) ); INSERT dbo.YourTable VALUES ('1.1.1.1','Data Center A','10ms'), ('1.1.1.1','Data Center B','12ms'), ('1.1.1.1','Data Center C','5ms'), ('1.1.1.2','Data Center A','50ms'); DECLARE @cols nvarchar(nax) = N'', @sql nvarchar(max); SELECT @cols = (SELECT ',' + QUOTENAME(sourceDataCenter) FROM dbo.YourTable GROUP BY sourceDataCenter ORDER BY sourceDataCenter FOR XML PATH(''), TYPE).value(N'./text()[1]', N'nvarchar(max)'); SELECT @sql = N'SELECT destinationIP' + @cols + ' FROM dbo.YourTable AS x PIVOT ( MAX(latency) FOR sourceDataCenter IN (' + STUFF(@cols,1,1,'') + ') ) AS p ORDER BY destinationIP;'; EXEC sys.sp_executesql @sql;