将按行的表转换为按列的表

时间:2019-04-09 07:20:40

标签: sql sql-server tsql pivot dynamic-pivot

我有一个按列明智的格式设计的表格,如下所示:

+------+---------+-------------+------------+
| S_ID | S_NAME  | MARK_NUMBER | MARK_VALUE |
+------+---------+-------------+------------+
|    1 | TEST    | MARK1       |         50 |
|    1 | TEST    | MARK2       |         60 |
|    1 | TEST    | MARK3       |         70 |
|    2 |  TEST_! | MARK1       |         40 |
|    2 |  TEST_! | MARK2       |         50 |
|    2 |  TEST_! | MARK3       |         40 |
+------+---------+-------------+------------+

MARK_NUMBER列将带有'N'个标记。我不能定义它/静态配置它(如其他SO答案所述)。我需要将该表转换为列明智的格式,如下所示:

 S_ID   S_Name  MARK1   MARK2   MARK3
   1    TEST    50        60    70
   2    TEST_!  40        50    40

2 个答案:

答案 0 :(得分:2)

尝试一下:

CREATE TABLE #DataSource
(
    [S_ID] INT
   ,[S_NAME] VARCHAR(12)
   ,[MARK_NUMBER] VARCHAR(12)
   ,[MARK_VALUE] INT
);

INSERT INTO #DataSource ([S_ID], [S_NAME], [MARK_NUMBER], [MARK_VALUE])
VALUES (1, 'TEST', 'MARK1', 50)
      ,(1, 'TEST', 'MARK2', 60)
      ,(1, 'TEST', 'MARK3', 70)
      ,(2, 'TEST_!', 'MARK1', 40)
      ,(2, 'TEST_!', 'MARK2', 50)
      ,(2, 'TEST_!', 'MARK3', 40);

DECLARE @DynammicTSQLStatement NVARCHAR(MAX)
       ,@DynamicPIVOTColumns NVARCHAR(MAX);


SET @DynamicPIVOTColumns = STUFF
                          (
                                (
                                SELECT ',[' + CAST([MARK_NUMBER] AS VARCHAR(12)) + ']'
                                FROM #DataSource
                                GROUP BY [MARK_NUMBER]
                                ORDER BY [MARK_NUMBER]
                                FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                          );

SET @DynammicTSQLStatement = N'
SELECT *
FROM #DataSource
PIVOT
(
    MAX([MARK_VALUE]) FOR [MARK_NUMBER] IN (' + @DynamicPIVOTColumns + ')
) PVT';

EXEC sp_executesql @DynammicTSQLStatement;

DROP TABLE #DataSource;

enter image description here

答案 1 :(得分:0)

我的解决方案是动态PIVOT:

DROP TABLE IF EXISTS #mytemptable
CREATE TABLE #mytemptable
(
   S_ID int
  ,S_NAME varchar(20)
  ,MARK_NUMBER varchar(20)
  ,MARK_VALUE int
)

INSERT INTO #mytemptable VALUES
(1,'TEST   ','MARK1',50),
(1,'TEST   ','MARK2',60),
(1,'TEST   ','MARK3',70),
(2,' TEST_!','MARK1',40),
(2,' TEST_!','MARK2',50),
(2,' TEST_!','MARK3',40)

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(MARK_NUMBER)
  FROM (SELECT DISTINCT p.MARK_NUMBER FROM #mytemptable AS p) AS x;
SET @sql = N'
SELECT *
FROM
(     select S_ID, S_NAME, MARK_VALUE, MARK_NUMBER from #mytemptable
) AS j
PIVOT
(
  SUM(MARK_VALUE) FOR MARK_NUMBER IN ('
  + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
  + ')
) AS p;';
PRINT @sql;
EXEC sp_executesql @sql;

DROP TABLE IF EXISTS #mytemptable