2011-02-12 90 views
3

上三角矩陣如果我有一個表(上三角矩陣),數據類型爲浮動,就像一個例子:如何轉在SQL Server

columns_1 columns_2 columns_3 columns_4 
    1   12   13   14 
    null    1   23   24 
    null   null   1   34 
    null   null  null   1  

什麼辦法做我必須遵循得到以下?

columns_1 columns_2 columns_3 columns_4 
      1  12  13  14 
      12   1  23  24 
      13  23   1  34 
      14  24  34   1 

這是SQL Server 2008中可能的嗎?

+0

對於給定的固定數目的列和行?那些包含混合詞彙和數字的列的數據類型是什麼? – 2011-02-12 23:04:32

+0

那麼,數據類型是浮動,矩陣(表格)的維度是已知的 – cMinor 2011-02-12 23:10:00

回答

2

下面介紹一種方法。

CREATE PROC dbo.Transpose @TableSchema sysname, 
          @TableName sysname, 
          @Debug  bit = 0 
AS 

    DECLARE @N INT 

    DECLARE @cols TABLE(
    idx INT NOT NULL IDENTITY(1, 1) PRIMARY KEY, 
    col int NOT NULL) 

    INSERT INTO @cols 
    SELECT CAST(CASE WHEN COLUMN_NAME NOT LIKE '%[^0-9]%' THEN COLUMN_NAME END AS INT) AS col 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_SCHEMA = @TableSchema 
     AND TABLE_NAME = @TableName 
     AND COLUMN_NAME NOT LIKE '%[^0-9]%' 
    ORDER BY col 

    SET @N = @@ROWCOUNT 

    IF @N = 0 
     OR EXISTS(SELECT * 
       FROM @cols 
       WHERE idx <> col) 
    BEGIN 
     RAISERROR ('Incompatible table passed',16,1) 
     RETURN 
    END 

    DECLARE @collist nvarchar(max) 

    SELECT @collist = COALESCE(@collist + ',', '') + QUOTENAME(col) 
    FROM @cols 

DECLARE @dynsql nvarchar(max) = N' 
WITH cte1 
    AS (SELECT *, 
       (SELECT ' + CAST(@N+1 AS VARCHAR(10)) + ' - COUNT(c) 
       FROM (VALUES' + REPLACE(REPLACE(@collist,']','])'),'[','([') + ') T (c)) AS RN 
     FROM ' + QUOTENAME(@TableSchema) + '.' + QUOTENAME(@TableName) + '), 
    cte2 
    As (SELECT * 
     FROM cte1 UNPIVOT (data FOR col IN (' + @collist + ')) AS unpvt), 
    cte3 
    As (SELECT RN, 
       data, 
       col 
     FROM cte2 
     UNION ALL 
     SELECT CAST(col as int), 
       data, 
       RN 
     FROM cte2) 
SELECT ' + @collist + ' 
FROM cte3 
PIVOT(max (data) FOR col IN (' + @collist + ')) AS pvt' 

IF @Debug = 1 
    SELECT @dynsql as [processing-instruction(x)] FOR XML PATH 

EXEC (@dynsql) 

示例用法

CREATE TABLE dbo.BaseData(
    [1] float, 
    [2] float, 
    [3] float, 
    [4] float) 

INSERT INTO dbo.BaseData 
SELECT 1,12,13,14 UNION ALL 
SELECT NULL,1,23,24 UNION ALL 
SELECT NULL, NULL, 1,34 UNION ALL 
SELECT NULL, NULL, NULL, 1; 

GO 

EXEC dbo.Transpose 'dbo', 'BaseData', 0