如何在SQL Server的T-SQL中透视数据

时间:2015-10-08 23:10:21

标签: sql-server tsql sql-server-2014

我有一个具有以下结构的表,其中“SymbolQuoteID”有不同类型的结果。

AnalysisResultID    SymbolQuoteID   ResultTypeID    Result            Updated
11                  368             1               48.6750775191538  2015-10-08 22:09:15.680
12                  368             2               47.7401046493826  2015-10-08 22:09:15.680
13                  368             3               47.3978529584944  2015-10-08 22:09:15.680
14                  368             4               43.4227483517635  2015-10-08 22:09:15.680
15                  369             1               44.9316592945153  2015-10-08 22:09:15.680
16                  369             2               48.8348167760945  2015-10-08 22:09:15.680
17                  369             3               51.6463393199821  2015-10-08 22:09:15.680
18                  369             4               51.7885923247485  2015-10-08 22:09:15.680

我需要选择数据,使其格式如下,其中ResultTypeID是列标题,相应的Result列值是列数据。没有聚合,只有Result值。此外,ResultTypeID的值的数量在单个查询中将是一致的,但可能因查询而异。例如,有一次它们可能是1到4,另一次是1到7,等等。因此,数据透视表中的列数将根据数据而变化。

SymbolQuoteID                1                 2                 3                 4                 
368           48.6750775191538  47.7401046493826  47.3978529584944  43.4227483517635
369           44.9316592945153  48.8348167760945  51.6463393199821  51.7885923247485

似乎PIVOT可能有效但我以前没用过它。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

您可以使用动态PIVOT

SQL Fiddle

DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);

SET @cols = 
    STUFF((
        SELECT DISTINCT ',' + QUOTENAME(ResultTypeID) 
        FROM tbl 
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 
    , 1, 1, '')

SET @query = 
    'SELECT SymbolQuoteID, ' + @cols + '
    FROM (
        SELECT
            SymbolQuoteID, ResultTypeID, Result
        FROM tbl
    )t
    PIVOT 
    (
        MAX(Result)
        FOR ResultTypeID IN (' + @cols + ')
    ) p '

PRINT (@query)
EXEC (@query)

您也可以使用dynamic crosstab执行此操作:

SQL Fiddle

DECLARE @maxResultTypeId INT
SELECT TOP 1 @maxResultTypeId = ResultTypeId FROM tbl ORDER BY ResultTypeID DESC

DECLARE @sql NVARCHAR(MAX) = ''

SELECT @sql = 
'SELECT
    SymbolQuoteID' + CHAR(10)

SELECT @sql = @sql +
'   , MAX(CASE WHEN ResultTypeId = ' + CONVERT(VARCHAR(3), rn) + ' THEN Result  END) AS ' + QUOTENAME(rn) + CHAR(10)
FROM(
    SELECT TOP(@maxResultTypeId)
        ROW_NUMBER() OVER(ORDER BY (SELECT NULL))  AS rn
    FROM sys.columns
)t

SELECT @sql = @sql +
'FROM tbl
GROUP BY SymbolQuoteID'

PRINT (@sql)
EXEC (@sql)

答案 1 :(得分:0)

SELECT * FROM 
(
SELECT SymbolQuoteID   
      ,ResultTypeID    
      ,Result
FROM TableName ) t
 PIVOT (SUM(Result)
        FOR ResultTypeID
        IN ([1],[2],[3],[4])
       )p