使用 T-SQL 将列动态转换为行

Transform Columns to Rows dynamically using T-SQL

我有以下 table 需要将列转换为行

tbl_Survey:

      SurveyID   Quest_1  Quest_2  Quest_3
             7        1         1        1
             8        2         2        2
             9        3         3        3
     
 

我需要得到以下结果:

       SurveyID  Questions  Rating 
              7    Quest_1      1
              7    Quest_2      1
              7    Quest_3      1
              8    Quest_1      2
              8    Quest_2      2
              8    Quest_3      2
              9    Quest_1      3
              9    Quest_2      3
              9    Quest_3      3 
    

为了得到这个结果,我使用了以下代码:

       SELECT [SurveyID], [Question], [Rating]
       FROM [dbo].[tbl_Survey]

       UNPIVOT
        (
         [Rating]
          FOR [Question] in ([Quest_1], [Quest_2], [Quest_3])
        ) AS SurveyUnpivot

但是,我的 Quest_1、Quest_2、Quest_3 值可能会被更改/甚至添加一个新值...

有没有办法对它们进行编码,以便它可以用于任何文本值(不仅用于 Quest_1 2 3)? 不需要 UNPIVOT...可以是任何其他方式

谢谢

我更喜欢在这里使用联合,因为 PIVOTUNPIVOT 所需语法的冗长性质:

SELECT SurveyID, 'Quest_1' AS Questions, Quest_1 AS Rating FROM tbl_Survey UNION ALL
SELECT SurveyID, 'Quest_2', Quest_2 FROM tbl_Survey UNION ALL
SELECT SurveyID, 'Quest_3', Quest_3 FROM tbl_Survey
ORDER BY SurveyID, Rating;

你需要做一个动态UNPIVOT。检查下面的例子:

DROP TABLE IF EXISTS [dbo].[DataSource];

CREATE TABLE [dbo].[DataSource]
(
    [SurveyID] INT
   ,[Quest_1] INT
   ,[Quest_2] INT
   ,[Quest_3] INT
);

INSERT INTO [dbo].[DataSource] ([SurveyID], [Quest_1], [Quest_2], [Quest_3])
VALUES (7, 1, 1, 1)
      ,(8, 2, 2, 2)
      ,(9, 3, 3, 3);

GO

DECLARE @DynamicTSQLStatement NVARCHAR(MAX);
DECLARE @DynamicTSQLUnpivotColumns NVARCHAR(MAX);

SET @DynamicTSQLUnpivotColumns = STUFF
(
    (
        SELECT ',' + QUOTENAME([name])
        FROM [sys].[columns]
        WHERE [object_id] = OBJECT_ID('[dbo].[DataSource]')
            AND [name] <> 'SurveyID'
        ORDER BY [name]
        FOR XML PATH(''), TYPE
    ).value('.', 'VARCHAR(MAX)')
    ,1
    ,1
    ,''
);

SET @DynamicTSQLStatement = N'
SELECT [SurveyID], [Question], [Rating]
FROM [dbo].[DataSource]
UNPIVOT
(
    [Rating] FOR [Question] in (' + @DynamicTSQLUnpivotColumns + ')
) AS SurveyUnpivot';

EXEC sp_executesql @DynamicTSQLStatement;