【问题标题】:Convert row wise table to column wise将逐行表转换为逐列
【发布时间】:2019-08-30 09:54:07
【问题描述】:

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

+------+---------+-------------+------------+
| 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

【问题讨论】:

  • 您需要使用 Pivot 才能达到预期的效果。由于可能有N个标记,动态查询可能是解决方案。

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


【解决方案1】:

试试这个:

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;

【讨论】:

    【解决方案2】:

    我的解决方案是动态 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-07-10
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多