Skip to content
Advertisement

Transform Columns to Rows dynamically using T-SQL

I have the following table where I need to transform Columns to Rows

tbl_Survey:

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

I need to have the following result:

       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 
    

To have this result I used the following code:

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

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

But, my Quest_1, Quest_2, Quest_3 values could potentially be changed / or even added a new once…

Are there ways to code them, so it can be used for any text values (not only for Quest_1 2 3)? Not necessary with the UNPIVOT… Could be any other way

Thank you

Advertisement

Answer

You need to make a dynamic UNPIVOT. Check the example below:

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;
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement