Skip to content
Advertisement

Transform and group row data into columns

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;
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement