SQL:矩阵的单元格条目

SQL: cell entries to matrix

我有一个 table,其中的条目表示矩阵中的单元格,其中 x、y 坐标和该位置的值如下所示:

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

所有列都是整数值,只有 COL3 具有唯一约束。我想要来自此 table 的矩阵形式的报告,其中列数和行数都可以变化,如下所示:

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

请注意,我不需要示例中那样的聚合函数。如果您需要更多详细信息,请告诉我。

样本TABLE

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 以获得所有 y 值的 x1, x2, x3。然后对同一个table使用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