代码之家  ›  专栏  ›  技术社区  ›  Karthik S

在SQL Server中透视和取消透视

  •  1
  • Karthik S  · 技术社区  · 6 年前

    我的表如下所示:

    enter image description here

    有50个这样的参数,超过2000个访问ID。

    我必须以这样的方式旋转表:访问ID是列,参数是行。我需要它,这样我就可以检查每次访问的ID、值为1的参数是什么以及有多少。

    我知道for pivot或unpivot只能通过使用聚合操作(如sum或count)来完成。但是由于访问ID和参数都是唯一的,所以如何继续旋转表。

    预期输出:

    enter image description here

    1 回复  |  直到 6 年前
        1
  •  1
  •   gotqn user3521065    6 年前

    在这里,您可以找到使用动态T-SQL语句的静态示例和示例:

    --DROP TABLE IF EXISTS [dbo].[DataSource]; 
    
    CREATE TABLE [dbo].[DataSource]
    (
        [VISIT_ID] INT
       ,[Parameter1] TINYINT
       ,[Parameter2] TINYINT
       ,[Parameter3] TINYINT
    );
    
    INSERT INTO [dbo].[DataSource] ([VISIT_ID], [Parameter1], [Parameter2], [Parameter3])
    VALUES (100, 1, 2, 1)
          ,(101, 4, 2, 1)
          ,(102, 2, 2, 0);
    
    -- static
    
    SELECT *
    FROM [dbo].[DataSource]
    UNPIVOT
    (
        [value] FOR [column] IN ([Parameter1], [Parameter2], [Parameter3])
    ) UNPVT
    PIVOT
    (
        MAX([value]) FOR [VISIT_ID] IN ([100], [101], [102])
    ) PVT;
    
    --- danymic
    
    DECLARE @DynamicTSQLStatement NVARCHAR(MAX)
           ,@DynamicColumnsP NVARCHAR(MAX)
           ,@DynamicColumnsU NVARCHAR(MAX);
    
    SET @DynamicColumnsP = STUFF
                            (
                                (
                                    SELECT ',[' + [name] + ']'
                                    FROM [sys].[columns]
                                    WHERE [name] LIKE 'Parameter%'
                                        AND [object_id] = OBJECT_ID('[dbo].[DataSource]')
                                    ORDER BY [name]
                                    FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                            );
    
    SET @DynamicColumnsU = STUFF
                            (
                                (
                                    SELECT ',[' + CAST([VISIT_ID] AS VARCHAR(12)) + ']'
                                    FROM [dbo].[DataSource]                             
                                    ORDER BY [VISIT_ID]
                                    FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                            );
    
    SET @DynamicTSQLStatement = N'
    SELECT *
    FROM [dbo].[DataSource]
    UNPIVOT
    (
        [value] FOR [column] IN (' + @DynamicColumnsP + ')
    ) UNPVT
    PIVOT
    (
        MAX([value]) FOR [VISIT_ID] IN (' + @DynamicColumnsU + ')
    ) PVT;';
    
    EXEC sp_executesql @DynamicTSQLStatement;