SQL:单元格条目到矩阵

时间:2015-01-30 20:27:32

标签: sql-server pivot-table

我有一个表格,表示带有x,y坐标的矩阵上的单元格,以及该位置的值,如下所示:

COL1   COL2    COL3
....   ....   ......
y1      x1    value11
y1      x2    value12
y1      x3    value13
y2      x1    value21
y2      x3    value23

所有列都是整数值,只有COL3具有唯一约束。我希望以矩阵形式从该表中获得一个报告,其中列数和行数可以变化,如下所示:

COL1   X1       X2       X3
..     ..       ..       ..
y1   value11  value12  value13
y2   value21   null    value23

目前我正在使用pivot table with dynamic columns,但我得到了这个:

COL1   X1        X2       X3
..     ..        ..       ..
y1   value11    null     null
y1    null    value12    null
y1    null      null    value13
y2   value21    null     null
y2    null      null    value23

请注意,我不需要像示例中那样的agregate函数。如果您需要更多详细信息,请与我们联系。

1 个答案:

答案 0 :(得分:1)

样本表

CREATE TABLE #TEMP(COL1 VARCHAR(50),COL2 VARCHAR(50),COL3 VARCHAR(50))

INSERT INTO #TEMP
SELECT 'y1', 'x1', 'value11'
UNION ALL
SELECT 'y1', 'x2', 'value12'
UNION ALL
SELECT 'y1', 'x3', 'value13'
UNION ALL
SELECT 'y2', 'x1', 'value21'
UNION ALL
SELECT 'y2', 'x3', 'value23'

获取数据透视列

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + COL2 + ']', '[' + COL2 + ']')
               FROM (SELECT DISTINCT COL2 FROM #TEMP) PV 
               ORDER BY COL2

应用CROSS JOIN获取所有x1, x2, x3值的y。然后使用LEFT JOIN到同一个表格,以标识每个yx1, x2x3。现在,当旋转时,您将以所需的方式获得矩阵。

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             (
                 SELECT DISTINCT C1.*,T.COL3 
                 FROM 
                 (
                    SELECT DISTINCT T2.COL1,T1.COL2
                    FROM #TEMP T1
                    CROSS JOIN #TEMP T2
                 )C1
                 LEFT JOIN #TEMP T ON T.COL2 = C1.COL2 AND T.COL1 = C1.COL1
             ) x
             PIVOT 
             (
                 MIN(COL3)
                 FOR COL2 IN (' + @cols + ')
            ) p
            ' 

EXEC SP_EXECUTESQL @query

编辑:

在为枢轴选择列时,请勿使用CASTCONVERT。在pivot

中进行
DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + COL2 + ']', '[' + COL2 + ']')
               FROM (SELECT DISTINCT COL2 FROM #TEMP) PV 
               ORDER BY COL2

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             (
                 SELECT DISTINCT C1.*,CAST(T.COL3 AS INT) COL3 
                 FROM 
                 (
                    SELECT DISTINCT T2.COL1,T1.COL2
                    FROM #TEMP T1
                    CROSS JOIN #TEMP T2
                 )C1
                 LEFT JOIN TEMP T ON T.COL2 = C1.COL2 AND T.COL1 = C1.COL1
             ) x
             PIVOT 
             (
                 MIN(COL3)
                 FOR COL2 IN (' + @cols + ')
            ) p
            ' 

EXEC SP_EXECUTESQL @query