将行数据转换并分组为列

时间:2013-12-07 16:53:53

标签: sql sql-server sql-server-2008 tsql

我正在寻找一种方法,将不同的行组合成一行的列。

我们来看这个示例表:

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

期望的输出:

destinationIP     Data Center A     Data Center B     Data Center C
-------------     -------------     -------------     -------------     
1.1.1.1           10ms              12ms              5ms
1.1.1.2           50ms

请注意,数据中心不一定是这三个,它们可能是N个不同的数据中心,我不会事先知道。

2 个答案:

答案 0 :(得分:1)

select   destinationIP
,        max(case when sourceDataCenter = 'Data Center A' then latency end) as A
,        max(case when sourceDataCenter = 'Data Center B' then latency end) as B
,        max(case when sourceDataCenter = 'Data Center C' then latency end) as C
from     YourTable
group by
         destinationIP

答案 1 :(得分:1)

使用一组已知的sourceDataCenter值,您只需使用简单的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;

如果您事先不知道数据中心的名称,则需要使用动态SQL生成等效查询,首先获取不同的值列表,然后将这些值添加到数据中心的两个相关位置。查询:

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(MAX) = N'', @sql NVARCHAR(MAX);

SELECT @cols = (SELECT ',' + QUOTENAME(sourceDataCenter)
  FROM dbo.YourTable GROUP BY sourceDataCenter ORDER BY sourceDataCenter
  FOR XML PATH(''), TYPE).value('.[1]','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 sp_executesql @sql;