2015-04-02 36 views
2

这是我的表格。如何使用动态T-SQL数据透视表更改输出

CREATE TABLE tpivot 
    ([col1] varchar(80), [col2] varchar(80), [col3] varchar(80), [col4] varchar(80), [col5] varchar(80)) 
; 

INSERT INTO tpivot 
    ([col1], [col2], [col3], [col4], [col5]) 
VALUES 
    ('Datum', 'EC', 'Mastercard', 'Postfinance', 'VISA'), 
    ('01.12.2014', '-204.9', '-88', '0', '-19'), 
    ('02.12.2014', '-352.9', '0', '79.9', '-20'), 
    ('03.12.2014', '-105', '-182', '0', '-436'), 
    ('04.12.2014', '-371', '-122,9', '-751', '-343') 

; 

我的目标是打开表格,使输出看起来像这样。

col1   col2   col3  col4  col5 
Datum  01.12.2014 02.12.2014 03.12.2014 04.12.2014 
EC   -204.9  -352.9  -105  -371 
Mastercard -88   0   -182  -112.9 
Postfinance 0   -79.9  0   -751 
VISA   -19   -20   -436  -346 

我需要一个动态数据透视表,因为我从每次可能有不同数量列的csv导入表。

有人可以帮助我吗?我甚至不能获取静态枢轴工作:(

感谢

+0

请帮助我这个:( – user2210516 2015-04-02 10:39:46

+0

为什么不改造现有的CSV在导入之前?例如在Excel中,你可以打开csv,转置整个数据矩阵并保存回来,有时候用输入格式比使用错误工具更容易改变输入格式,使用varchars混合不同的数据类型并输出数据集不是一个好的做法。 试图改变你解决这个任务的方式 – teran 2015-04-02 12:57:25

+0

这不是真正的枢轴转动。你从列“col1” - “col5”开始,你所需的输出具有相同的列。 – funkwurm 2015-04-02 13:59:06

回答

1

这里是我的动态SQL的解决方案。

IF OBJECT_ID('tPivot') IS NOT NULl 
    DROP TABLE tpivot; 

CREATE TABLE tpivot 
    (ID INT IDENTITY(1,1), [col1] varchar(100), [col2] varchar(100), [col3] varchar(100), [col4] varchar(100), [col5] varchar(100)); 
INSERT INTO tpivot 
    ([col1], [col2], [col3], [col4], [col5]) 
VALUES 
    ('Datum', 'EC', 'Mastercard', 'Postfinance', 'VISA'), 
    ('01.12.2014', '-204.9', '-88', '0', '-19'), 
    ('02.12.2014', '-352.9', '0', '79.9', '-20'), 
    ('03.12.2014', '-105', '-182', '0', '-436'), 
    ('04.12.2014', '-371', '-122,9', '-751', '-343'); 

DECLARE @ColList VARCHAR(MAX), 
     @IdList VARCHAR(MAX); 

SELECT @ColList = COALESCE(@ColList + ',','') + QUOTENAME(A.COLUMN_NAME), 
     @IdList = COALESCE(@IdList + ',','') + QUOTENAME(ROW_NUMBER() OVER (ORDER BY ORDINAL_POSITION)) 
FROM INFORMATION_SCHEMA.COLUMNS A 
WHERE TABLE_NAME = 'tPivot' 
     AND COLUMN_NAME ! ='ID' 

--SELECT @ColList 
--SELECT @IdList 


EXEC (
'WITH CTE 
AS 
(
    SELECT * 
    FROM 
    (
     SELECT ID, 
       Column_Name, 
       ROW_NUMBER() OVER (PARTITION BY ID ORDER BY col) row_num, 
       val 
     FROM tPivot A 
     INNER JOIN (SELECT Column_Name AS COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''tPivot'') B 
     ON A.ID = B.ORDINAL_POSITION - 1 
     UNPIVOT 
     (
      val for col in (' + @colList + ') 
     ) unpvt 
    ) A 
    PIVOT 
    (
     MAX(val) FOR column_name IN (' + @colList + ') 
    ) pvt 
) 

SELECT * 
FROM 
(
    SELECT ID, 
      row_num, 
      coalesce(' + @colList + ') val 
    FROM cte 
) A 
PIVOT 
(
    MAX(val) FOR ID IN (' + @IdList + ') 
) pvt' 
) 
+0

作品很有魅力,非常感谢。呵呵对我来说这并不容易,所以如果你想帮助我,我会很感激。 – user2210516 2015-04-07 07:51:34

+0

我明白。我在编写动态SQL时习惯于使用TERRIBLE。这是所有关于一次采取一步和练习!因此,我所做的就是编写我的脚本,然后查找哪些部分需要“动态”,如不断变化的列名称数量。我把这些变量。然后在我的脚本周围添加单引号,并开始放入我的动态变量。然后,我选择“我的代码”并在新的查询窗口中运行返回的代码。调试它并重试,直到它工作。一旦我开始工作,我将SELECT更改为EXEC('我的代码'),瞧!动态SQL诞生了! :) – Stephan 2015-04-07 11:28:50